import System
import clr
import sys
from Worksheet import *
from Worksheet.PropertyGroupEditor import *

clr.AddReference("Ansys.ACT.Interfaces")
import Ansys

from Ansys.ACT.Interfaces.Analysis import *
from Ansys.ACT.Interfaces.Common import *
from Ansys.ACT.Interfaces.DataModel import *
from Ansys.ACT.Interfaces.Geometry import *
from Ansys.ACT.Interfaces.Graphics import *
from Ansys.ACT.Interfaces.Mechanical import *
from Ansys.ACT.Interfaces.Mesh import *
from Ansys.ACT.Interfaces.Post import *
from Ansys.ACT.Interfaces.UserInterface import *
from Ansys.ACT.Interfaces.UserObject import *



ExtensionDir = os.path.dirname(os.path.realpath(__file__))
sys.path.append(ExtensionDir)


clr.AddReferenceToFileAndPath(os.path.join(ExtensionDir,r'LSDynaSolverExtension.dll'))
import LSDynaSolverExtension

from LSDynaSolverExtension import Glstat
from LSDynaSolverExtension import SpcForc
from LSDynaSolverExtension import BndOut
from LSDynaSolverExtension import RcForc
from LSDynaSolverExtension import Nodout
from LSDynaSolverExtension import Matsum
from LSDynaSolverExtension import SwForc
from LSDynaSolverExtension import LoadUtils
from LSDynaSolverExtension import IAsciiFigureController

import helper
import chart
import tabular



sizeentry = chart._collections['symbol'].entries['symbolsize']
sizeentry.default = 6

class TablePropertyFigureController(PGEditor):
    def __init__(self, api, load,prop):
        PGEditor.__init__(self,api,load,prop)
        self.api = api
        self.figure = chart.Figure()
        #self.panel = helper.MechanicalPanelHelper(self.api, self.figure, 'Graph')

        if LSDynaSolverExtension.InterfaceController.MechanicalIsReady(api) :
            self.panel = self.api.UserInterface.AttachControlToPanel(self.figure,MechanicalPanelEnum.Graph)
            self.prop = prop
            self.Name = prop.Name
            
    def onvalidate(self,load,prop):
        self.onshow(load,prop)

    def onapply(self,load,prop):
        PGEditor.onapply(self,load,prop)
        self.onshow(load,prop)

    def getcomponentunit(self,component):
        result = ''
        if (self.prop.Properties.GetByName(component) != None):
            return self.prop.Properties.GetByName(component).UnitString
        else:
            return result
    

    def onhide(self, load,prop):
        if self.figure != None :
            self.panel.Hide()
            #self.figure.hide()

    def onremove(self, load,prop):
        if self.figure != None :
            #self.panel.Dispose()
            self.figure.dispose()
            #self.figure.close()


    def onshow(self,load,prop):
        if prop.Visible :
            self.figure.clear()
            if self.prop.Properties.Count >= 2 :
                unit1 = self.getcomponentunit(self.prop.Properties[0].Name)
                unit2 = self.getcomponentunit(self.prop.Properties[1].Name)
                self.figure.title(self.Name)
                self.figure.xlabel(self.prop.Properties[0].Name + ' [' + unit1 + ']' )
                self.figure.ylabel(self.prop.Properties[1].Name + ' [' + unit2 + ']' )        
                
                mydict = self.getdict()
                x = self.getpropertyvalues(0)
                y = self.getpropertyvalues(1)
                self.figure.plot(x, y, 'c-', linewidth=2.)
        
                #self.figure.show(self.api, location='Graph')
                self.panel.Show()
        else:
            self.panel.Hide()

    def getpropertyvalues(self,i):
        result = []
        rowid = 0
        while ((rowid < self.prop.RowCount)) :
            self.prop.ActiveRow = rowid
            value = self.prop.Properties[i].Value
            result.append(value)
            rowid += 1
        return result

    def GetTableDictionary(self):
        curveobj = {}
        rowid = 0
        while ((rowid < self.prop.RowCount)) :
            self.prop.ActiveRow = rowid
            key_d = self.prop.Properties[0].Value
            value = self.prop.Properties[1].Value
            curveobj[key_d] = value
            rowid += 1
        return curveobj


    def getdict(self):
        return self.GetTableDictionary()


class GlStatFigureController(PGEditor):
    def __init__(self, api, load,prop):
        PGEditor.__init__(self,api,load,prop)
        self.api = api
        self.prop = prop
        self.figure = chart.Figure()
        #self.panel = helper.MechanicalPanelHelper(self.api, self.figure, "Worksheet")
        self.panel = self.api.UserInterface.AttachControlToPanel(self.figure,MechanicalPanelEnum.Worksheet)
        self.glstat = Glstat()
        
        self.glstat.Init(api,load,prop)
        #Glstat.Init(api,load,prop)

    def onvalidate(self,load,prop):
        self.onshow(load,prop)
                

    def onapply(self,load,prop):
        PGEditor.onapply(self,load,prop)
        self.onshow(load,prop)

    def onhide(self, load,prop):
        if self.figure != None :
            self.panel.Hide()

    def oncleardata(self,load,prop):
        self.figure.clear()
        self.glstat.Clear()
        
    def ongenerate(self,load,prop):
        #self.__onshow(load,prop)
        return True
        
    def onremove(self, load,prop):
        if self.figure != None :
            self.panel.Close()
            self.figure.dispose()

    def onshow(self,load,prop):
        if load.State == 'solved' :
            self.__onshow(load,prop)

            
    def __onshow(self,load,prop):
        #if Glstat.IsNullOrEmpty():
        #    Glstat.Init(self.api,load,prop)
        
        if self.glstat.IsNullOrEmpty():
            self.glstat.Init(self.api,load,prop)
        
        self.figure.clear()    
        self.figure.xlabel('[s]' )
        #x = Glstat.GetTimeValues()
        x = self.glstat.GetTimeValues()
        if prop.RowCount == 1:
            self.figure.title(prop.Properties[0].Value + ' versus Time')
            self.figure.ylabel(prop.Properties[0].Value)            
            y = self.glstat.GetValues(load,prop.Properties[0])
            self.figure.plot(x, y, 'r-', linewidth=1. , symbolstyle='R', symbolsize = 2, variablelabel= prop.Properties[0].Value)
            self.figure.legend()
            self.panel.Show()
            

        if prop.RowCount > 1 :
            rowid = 0
            while ((rowid < prop.RowCount)) :
                prop.ActiveRow = rowid
                y = self.glstat.GetValues(load,prop.Properties[0])
                color = self.getcolor(rowid)
                self.figure.plot(x, y, color, linewidth=1. , symbolstyle='R', symbolsize = 2 , variablelabel= prop.Properties[0].Value)
                rowid += 1
            self.figure.title('Multiple Plots versus Time')
            self.figure.legend()
            self.panel.Show()
    
    def getcolor(self,id):
        count = chart._maps['color'].long_str_2_value.Count
        item = 0
        if id >= count :
            item = id % count
        else :
            item = id
        color = chart._maps['color'].short_str_2_long_str.keys()[item]
        
        if color == 'w' :
            color = 'r'
        
        return color

        #return chart._maps['color'].get_short_color_str(id)




class AsciiFigureController(IAsciiFigureController):
    def __init__(self, api, load,prop , ascii):
        self.api = api
        self.prop = prop
        self.figure = chart.Figure()
        #self.panel2 = helper.MechanicalPanelHelper(self.api, self.figure, 'Graph')
        self.panel2 = self.api.UserInterface.AttachControlToPanel(self.figure,MechanicalPanelEnum.Graph)
        # --- Create Tabular ---

        self.tab = tabular.Tabular()
        # --- Create Helper ---
        #self.tabularPanel = helper.MechanicalPanelHelper(self.api, self.tab, "TabularData")
        self.tabularPanel = self.api.UserInterface.AttachControlToPanel(self.tab,MechanicalPanelEnum.TabularData)
        # ---------------------

        self.ascii = ascii

        self.ascii.Init(api,load,prop)
        
        self._needupdate = True 

    def onvalidate(self,load,prop):
        self._needupdate = True
        load.Properties.GetByName("Type").ValueString = self.ascii.GetPropertyType(load,prop)
        self.onshow(load,prop)
                

    def onhide(self, load,prop):
        if self.figure != None :
            self.panel2.Hide()
            self.tabularPanel.Hide()

    def oncleardata(self,load,prop):
        self.figure.clear()
        self.ascii.Clear()
        self._needupdate = True
    
    def internalgenerate(self,load,prop):
        self.__updatefigure(load,prop)
        self.panel2.Show()
        self.tabularPanel.Show()
    
    def ongenerate(self,load,prop):
        try:
            self.__updatefigure(load,prop)
            self.panel2.Show()
            self.tabularPanel.Show()
        except:
            return True
        return True
        
    def onremove(self, load,prop):
        if self.figure != None :
            self.panel2.Close()
            self.figure.dispose()
            self.tab.dispose()

    def onshow(self,load,prop):
        if load.State == 'solved' :
            if self._needupdate:
                self.__onshow(load,prop)
            else:
                self.__onshow_noupdate(load,prop)
        else:
            if load.Analysis.Solver.State == 'solved' :
                if self._needupdate:
                    self.__onshow(load,prop)
                else:
                    self.__onshow_noupdate(load,prop)
                

    def __onshow_noupdate(self,load,prop):
        self.panel2.Show()
        self.tabularPanel.Show()
        
    def __onshow(self,load,prop):
        
        self.__updatefigure(load,prop)
        
        self.panel2.Show()
        self.tabularPanel.Show()
            
    def __updatefigure(self,load,prop):
    
        self.panel2.Hide()
        self.tabularPanel.Hide()
        
        if self.ascii.IsNullOrEmpty():
            self.ascii.Init(self.api,load,prop)
        # if we need to update the figure
        self.figure.clear()    
        self.figure.xlabel('[s]' )
        x = self.ascii.GetTimeValues()
        
        name = self.ascii.GetInfo(load,prop)
        self.figure.title(name + " " + prop.ValueString + ' versus Time')
        unitstring = self.ascii.GetUnitString(load,prop)
        self.figure.ylabel(name + " " + prop.ValueString + ' [' + unitstring + ']' )            
        y = self.ascii.GetValues(load,prop)
        self.figure.plot(x, y, 'r-', linewidth=1. , symbolstyle='R', symbolsize = 1, variablelabel= prop.ValueString)
        self.figure.legend()
        
        labels = ['Time[s]', prop.ValueString + ' [' + unitstring + ']']
        columns = [x,y]
        self.tab.setdata(labels, columns)
        
        self._needupdate = False
        
    
    
    def getcolor(self,id):
        return chart._maps['color'].get_short_color_str(id)

    def internalexport(self,load,prop):
        return LoadUtils.OnExportFile(self.api,load,prop,self.ascii)
        
class BndoutController(AsciiFigureController):
    def __init__(self, api, load,prop):
        ascii = BndOut()
        AsciiFigureController.__init__(self,api,load,prop,ascii)


class SpcForcController(AsciiFigureController):
    def __init__(self, api, load,prop):
        ascii = SpcForc()
        AsciiFigureController.__init__(self,api,load,prop,ascii)

class RcForcController(AsciiFigureController):
    def __init__(self, api, load,prop):
        ascii = RcForc()
        AsciiFigureController.__init__(self,api,load,prop,ascii)

class NodoutController(AsciiFigureController):
    def __init__(self, api, load,prop):
        ascii = Nodout()
        AsciiFigureController.__init__(self,api,load,prop,ascii)

class MatsumController(AsciiFigureController):
    def __init__(self, api, load,prop):
        ascii = Matsum()
        AsciiFigureController.__init__(self,api,load,prop,ascii)


class SwForcController(AsciiFigureController):
    def __init__(self, api, load,prop):
        ascii = SwForc()
        AsciiFigureController.__init__(self,api,load,prop,ascii)