import logging
from SystemInterface import Static
from Interface import Version,Application,SheetMetadata,RowMetadata,ColumnMetadata,CellMetadata
from Interface import Formula,Node,BaseNode,Task,ActivityDefinition,Branch, InputportMetadata, OutputportMetadata
from Interface import SubProcess,Level,MenuGroup,LayoutView,LayoutRow,LayoutColumn,LayoutCell,LevelRowSpan
from Interface import SearchDefinition,Criteria,Condition,Header,Hierarchy,Section,GridView,GridRow,GridColumn,GridCell,Style,RowSpan,TableStyle,Button
from Interface import ActivityPermission,Range,RangeValue, Property, Folder, ShortCut
from orangescape.model.engine.exception.Error import MetadataError
from orangescape.model.engine.exception.ErrorMessage import Server1007, Server1006, Server1008, Server2003
from orangescape.model.server.util.metadatautil import constructDescendantNodeList
from orangescape.model.engine.engineconstants import WORKFLOW

class StaticDevModel(Static):
    dynamicObj = None

    def __init__(self,dynamicObj):
        self.dynamicObj = dynamicObj

    def getSheetMetadataName(self):
        return self.getValue('SheetMetadataName')

    def getSheetId(self):
        return self.dynamicObj.getSheetId()

    def getSheetName(self):
        return self.getValue('SheetName')

    def getDynamicObject(self):
        return self.dynamicObj

    def getValue(self,name):
        return self.dynamicObj.getValue(name)

    def getOneToManyReferenceCell(self,cellName,sheetMetadataName):
        oneToManyReferenceCellList = self.getDynamicObject().getSheetMetadata().getOneToManyList()
        for refCell in oneToManyReferenceCellList:
            if sheetMetadataName == refCell.getSheetMetadata().getSheetMetadataName() and cellName == refCell.getCellName():
                return refCell
        return None

    def get(self, Class, name):
        if self.getValue(name) and len(self.getValue(name))>0:
            sheetMetadata =  self.dynamicObj.getCellMetadata(name).getReferredSheetMetadata()
            return Class(self.dynamicObj.getSession().get(self.getValue(name),sheetMetadata))
        return None

    def getList(self,cellName,sheetMetadataName):
        refCell = self.getOneToManyReferenceCell(cellName,sheetMetadataName)
        return self.dynamicObj.getSession().getList(self.dynamicObj,refCell)

class VersionDevModel(Version,StaticDevModel):
    def getVersionNumber(self):
        return self.getValue('VersionNumber')

    def getApplicationList(self):
        metadataList = self.getList('Version','Application')
        return [ApplicationDevModel(obj) for obj in metadataList]

class ApplicationDevModel(Application,StaticDevModel):
    sheetMetadataDict = dict()

    def __init__(self,dynamicObj, formMapping=None, actionMapping=None):
        self.dynamicObj = dynamicObj
        self.formMapping = formMapping
        self.actionMapping = actionMapping

    def getApplicationName(self):
        return self.getValue('SheetName')

    def getVersion(self):
        return self.get(VersionDevModel,'Version')

    def getSheetMetadataList(self):
        sheetMetadataIdDict = dict()
        sheetMetadataList = self.getSheetMetadataObjectList()
        for sheetMetadataObj in sheetMetadataList:
            sheetMetadataIdDict[sheetMetadataObj.getSheetId()] = sheetMetadataObj.getSheetName()
        return sheetMetadataIdDict

    def getSheetMetadataObjectList(self):
        metadataList = self.getList('Application','SheetMetadata')
        return [SheetMetadataDevModel(obj) for obj in metadataList]

    def getFolderList(self):
        metadataList = self.getList('Application','Folder')
        return [FolderDevModel(obj) for obj in metadataList]

    def getLevelList(self):
        metadataList = self.getList('Application','Level')
        return [LevelDevModel(obj) for obj in metadataList]

    def getVersionList(self):
        metadataList = self.getList('Application','Version')
        return [VersionDevModel(obj) for obj in metadataList]

    def getStyleList(self):
        metadataList = self.getList('Application','Style')
        return [StyleDevModel(obj) for obj in metadataList]

    def getTableStyleList(self):
        metadataList = self.getList('Application','TableStyle')
        return [TableStyleDevModel(obj) for obj in metadataList]

    def getMenuGroupList(self):
        metadataList = self.getList('Application','MenuGroup')
        return [MenuGroupDevModel(obj) for obj in metadataList]

    def getRangeList(self):
        metadataList = self.getList('Application','Range')
        return [RangeDevModel(obj) for obj in metadataList]

    def constructsheetMetadataDict(self):
        sheetMetadataDict = dict()
        sheetMetadataList = self.getSheetMetadataObjectList()
        for sheetMetadataObj in sheetMetadataList:
            sheetMetadataDict[sheetMetadataObj.getSheetName()] = sheetMetadataObj
        self.sheetMetadataDict=sheetMetadataDict

    def getSheetMetadataDict(self):
#        if len(self.sheetMetadataDict) == 0:
        self.constructsheetMetadataDict()
        return self.sheetMetadataDict

    def getSheetMetadata(self, name):
        if self.getSheetMetadataDict().__contains__(name):
            return self.getSheetMetadataDict().get(name)
        raise MetadataError , Server1007 % (name, self.getApplicationName())

    def getSheetMetadataById(self,idVal):
        sheetList = [sheetMetadataObj for sheetMetadataObj in self.getSheetMetadataObjectList() if sheetMetadataObj.getSheetId().__eq__(idVal)]
        if len(sheetList)==0:
            msg = 'SheetMetadata not found for the id %s'%(idVal)
            raise MetadataError , Server1008 % (idVal)
        return sheetList.pop()

    def getAppRoles(self):
        return self.getValue('AppRoles')

    def setFormMapping(self, formMapping):
        self.formMapping = formMapping

    def setActionMapping(self, actionMapping):
        self.actionMapping = actionMapping

    def getFormMapping(self):
        return self.formMapping

    def getActionMapping(self):
        return self.actionMapping

class SheetMetadataDevModel(SheetMetadata,StaticDevModel):
    publicCellMetadataDict = dict()
    branchDict = dict()

    def getSheetMetadataName(self):
        return self.getValue('SheetName')

    def isSystemModel(self):
        return self.getValue('SystemModel')

    def getApplication(self):
        return self.get(ApplicationDevModel,'Application')

    def getRowMetadataList(self):
        metadataList = self.getList('SheetMetadata','RowMetadata')
        return [RowMetadataDevModel(obj) for obj in metadataList]

    def getColumnMetadataList(self):
        metadataList = self.getList('SheetMetadata','ColumnMetadata')
        return [ColumnMetadataDevModel(obj) for obj in metadataList]

    def getCellMetadataList(self):
        metadataList = self.getList('SheetMetadata','CellMetadata')
        return [CellMetadataDevModel(obj) for obj in metadataList]

    def getProtectedCellMetadataList(self):
        metadataList = self.getList('ProtectedSheetMetadata','CellMetadata')
        return [CellMetadataDevModel(obj) for obj in metadataList]

    def getOneToManyList(self):
        metadataList = self.getList('ReferredSheetMetadata','CellMetadata')
        return [CellMetadataDevModel(obj) for obj in metadataList]

    def getManyToOneList(self):
        metadataList = self.getList('SheetMetadata','CellMetadata')
        return [CellMetadataDevModel(obj) for obj in metadataList if obj.getValue('ReferredSheetMetadata') is not None]

    def getSectionList(self):
        metadataList = self.getList('SheetMetadata','Section')
        return [SectionDevModel(obj) for obj in metadataList]

    def getGridViewList(self):
        metadataList = self.getList('SheetMetadata','GridView')
        gridViewDict = dict()
        for obj in metadataList:
            gridViewDict[obj.getSheetId()] = obj.getSheetName()
        return gridViewDict

    def getQGridViewList(self):
        metadataList = self.getList('QSheetMetadata','GridView')
        gridViewDict = dict()
        for obj in metadataList:
            gridViewDict[obj.getSheetId()] = obj.getSheetName()
        return gridViewDict

    def constructPublicCellMetadataDict(self):
        cellMetadataDict = dict()
        cellMetadataList = self.getCellMetadataList()
        for cellObj in cellMetadataList:
            cellMetadataDict[cellObj.getCellName()] = cellObj
        self.publicCellMetadataDict=cellMetadataDict

    def getPublicCellMetadataDict(self):
        if len(self.publicCellMetadataDict) == 0:
            self.constructPublicCellMetadataDict()
        return self.publicCellMetadataDict

    def getPublicCellMetadata(self, name):
        if self.getPublicCellMetadataDict().__contains__(name):
            return self.getPublicCellMetadataDict().get(name)
        raise MetadataError , Server1006 % (name, self.getSheetMetadataName())

    def getCellMetadataById(self,idVal):
        return [cellMetadataObj for cellMetadataObj in self.getCellMetadataList() if cellMetadataObj.getSheetId().__eq__(idVal)].pop()

    def getBranchList(self):
        branchList = self.getList('SheetMetadata','Branch')
        branchDevMetadataList = [BranchDevModel(obj) for obj in branchList]
        return branchDevMetadataList

    def constructBranchDict(self):
        branchList = self.getBranchList()
        for branch in branchList:
            self.branchDict[branch.getSheetName()] = branch

    def getBranchDict(self):
        if len(self.branchDict) == 0:
            self.constructBranchDict()
        return self.branchDict

    def getBranch(self, name):
        if self.getBranchDict().__contains__(name):
            return self.getBranchDict().get(name)
        raise MetadataError , Server2003 % (name, self.getSheetMetadataName())

    def getFolder(self):
        return self.get(FolderDevModel,'Folder')

    def getShortCutList(self):
        metadataList = self.getList('SheetMetadata','ShortCut')
        return [ShortCutDevModel(obj) for obj in metadataList]

    def isPublic(self):
        return self.getValue('IsPublic')

    def getPublicName(self):
        return self.getValue('PublicName') or self.getSheetName()

    def getWorkFlowRoot(self):
        branchList = [branch for branch in self.getBranchList() if branch.getProcessType()==WORKFLOW]
        if len(branchList)>0:
            return branchList.pop()
        return None

    def getActivityDefinitionById(self, actDefId):
        metadata = self.dynamicObj.getSession().getApplication().getSheetMetadata('ActivityDefinition')
        actInstance = self.dynamicObj.getSession().getIfExists(actDefId, metadata)
        if actInstance:
            return ActivityDefinitionDevModel(actInstance)
        return None

    def getBranchById(self,branchId):
        metadata = self.dynamicObj.getSession().getApplication().getSheetMetadata('Branch')
        branchInstance = self.dynamicObj.getSession().getIfExists(branchId, metadata)
        if branchInstance:
            return BranchDevModel(branchInstance)
        return None

    def getStartActivity(self):
        workFlowRootbranch = self.getWorkFlowRoot()
        if workFlowRootbranch:
            actList = workFlowRootbranch.getActivityDefinitionList()
            if len(actList) > 0:
                return actList[0]
        return None

    def isMonitorEnabled(self):
        return not self.getValue('DisableProcessInstance')

    def getSearchDefinitionList(self):
        metadataList = self.getList('SheetMetadata','SearchDefinition')
        return [SearchDefinitionDevModel(obj) for obj in metadataList]

    def getSearchDefinitionById(self, idVal):
        metadata = self.dynamicObj.getSession().getApplication().getSheetMetadata('SearchDefinition')
        searchDefInstance = self.dynamicObj.getSession().getIfExists(idVal, metadata)
        if searchDefInstance:
            return SearchDefinitionDevModel(searchDefInstance)
        return None

    def getMetadataVersion(self):
        return  self.getValue('MetadataVersion')

    def isTrash(self):
        return  self.getValue('IsTrash')

class RowMetadataDevModel(RowMetadata,StaticDevModel):
    def getRowNumber(self):
        return self.getValue('RowNumber')

    def getRowHeight(self):
        return self.getValue('RowHeight')

    def getStyle(self):
        return self.get(StyleDevModel,'Style')

    def getSheetMetadata(self):
        return self.get(SheetMetadataDevModel,'SheetMetadata')

    def getCellMetadataList(self):
        metadataList = self.getList('RowMetadata','CellMetadata')
        return [CellMetadataDevModel(obj) for obj in metadataList]

    def getPreviousRef(self):
        return self.get(RowMetadataDevModel,'PreviousRef')

class ColumnMetadataDevModel(ColumnMetadata,StaticDevModel):
    def getColumnName(self):
        return self.getValue('ColumnName')

    def getColumnNumber(self):
        return self.getValue('ColumnNumber')

    def getColumnWidth(self):
        return self.getValue('ColumnWidth')

    def getSheetMetadata(self):
        return self.get(SheetMetadataDevModel,'SheetMetadata')

    def getCellMetadataList(self):
        metadataList = self.getList('ColumnMetadata','CellMetadata')
        return [CellMetadataDevModel(obj) for obj in metadataList]

    def getPreviousRef(self):
        return self.get(ColumnMetadataDevModel,'PreviousRef')

class CellMetadataDevModel(CellMetadata,StaticDevModel):
    results = None

    def getCellName(self):
        return self.getValue('CellName')

    def getCellDisplayName(self):
       return self.getValue('CellDisplayName')

    def getCellType(self):
        return self.getValue('CellType')

    def getWidgetType(self):
        return self.getValue('WidgetType')

    def getRowSpanned(self):
        return self.getValue('RowSpanned')

    def getColumnSpanned(self):
        return self.getValue('ColumnSpanned')

    def getDefaultValue(self):
        return self.getValue('DefaultValue')

    def getCellValue(self):
        return self.getValue('CellValue')

    def isCascade(self):
        if self.getValue('Cascade') is not None:
            if type(self.getValue('Cascade'))==str or type(self.getValue('Cascade'))==unicode:
                return float(self.getValue('Cascade'))
        return self.getValue('Cascade')

    def getRowMetadata(self):
        return self.get(RowMetadataDevModel,'RowMetadata')

    def getColumnMetadata(self):
        return self.get(ColumnMetadataDevModel,'ColumnMetadata')

    def getStyle(self):
        return self.get(StyleDevModel,'Style')

    def getSheetMetadata(self):
        return self.get(SheetMetadataDevModel,'SheetMetadata')

    def getReferredSheetMetadata(self):
        return self.get(SheetMetadataDevModel,'ReferredSheetMetadata')

    def getRowSpan(self):
        return self.get(RowSpanDevModel,'RowSpan')

    def getRowSpanList(self):
        metadataList = self.getList('CellMetadata','RowSpan')
        return [RowSpanDevModel(obj) for obj in metadataList]

    def getColumnNumber(self):
        return self.getValue('ColumnNumber')

    def getRowNumber(self):
        return self.getValue('RowNumber')

    def getColumnNUmber(self):
        return self.getValue('ColumnNumber')

    def getHeaderList(self):
        metadataList = self.getList('CellMetadata','Header')
        return [HeaderDevModel(obj) for obj in metadataList]

    def getFormulaList(self):
        metadataList = self.getList('CellMetadata','Formula')
        return [FormulaDevModel(obj) for obj in metadataList]

    def getDescendentNodeList(self):
        return constructDescendantNodeList(self.getNodeList())
#        return self.getNodeList()

    def getNodeList(self):
        metadataList = self.getList('CellMetadata','Node')
        return [NodeDevModel(obj) for obj in metadataList]

    def getDescendantCellMetadata(self,node):
        if node.getValue('Formula'):
            formula = node.getFormula()
            if formula.getCellMetadata() is not None:
                cellMetadata = formula.getCellMetadata()
                return cellMetadata
            return None
        return self.getDescendantCellMetadata(node.getNode())

    def getNodeProperties(self,node,dictValue):
        parentNode = node.getNode()
        if parentNode:
            nodeType = parentNode.getNodeType()
        else:
            nodeType = 'Function'
        dictValue['nodeType']=nodeType
        if nodeType.__eq__('Fetch3DFunction') or nodeType.__eq__('Aggrigate3DFunction'):
            nodeList = parentNode.getNodeList()
            nodeList.sort(self.sortNodeCompare)
            dictValue['refCellMetadata'] = nodeList[0].getCellMetadata()
            if len(nodeList) == 4:
                dictValue['synchronous']=nodeList[3].getNodeValue()

    def sortNodeCompare(self,a,b):
        return cmp(a.getArgNo(),b.getArgNo())

    def isNamedCell(self):
        return self.getValue('CellName') is not None

    def isReferenceCell(self):
        return self.getValue('ReferredSheetMetadata') is not None

    def isFormula(self):
        if self.results is None:
            self.results = self.getFormulaList()
        return len(self.results)>0

    def isHidden(self):
        return self.getValue('Hidden')

    def isHeader(self):
        return self.getValue('IsHeader')

    def getFormat(self):
        return self.getValue('OutputFormat')

    def getCategory(self):
        return self.getValue('OutputCategory')

    def getFinalFormat(self):
        return self.getValue('FinalFormat')

    def getFinalCategory(self):
        return self.getValue('FinalCategory')

    def getSearchDefinitionList(self):
        metadataList = self.getList('CellMetadata','SearchDefinition')
        return [SearchDefinitionDevModel(obj) for obj in metadataList]

    def getIsFormulaError(self):
        return self.getValue('FormulaError')>0

    def getOutputportMetadataList(self):
        metadataList = self.getList('CellMetadata','OutputportMetadata')
        return [OutputportMetadataDevModel(obj) for obj in metadataList]

    def getInputportMetadataList(self):
        metadataList = self.getList('CellMetadata','InputportMetadata')
        return [InputportMetadataDevModel(obj) for obj in metadataList]

    def isStr(self):
        return self.getValue('IsStr')

    def isSystemCell(self):
        return self.getRowNumber()<0.0 or self.getColumnNUmber()<0.0

    def getOutputFormat(self):
        return self.getValue('OutputFormat')

    def getInputFormat(self):
        return self.getValue('FinalFormat')

    def getCellFloatValue(self):
        return self.getValue('CellFloatValue')

    def getTextLength(self):
        return self.getValue('TextLength')

class FormulaDevModel(Formula,StaticDevModel):
    def getCellMetadata(self):
        return self.get(CellMetadataDevModel,'CellMetadata')

    def getNodeList(self):
        metadataList = self.getList('Formula','Node')
        return [NodeDevModel(obj) for obj in metadataList]

    def getActivityDefinition(self):
        return self.get(ActivityDefinitionDevModel,'ActivityDefinition')

    def getBranch(self):
        return self.get(BranchDevModel, 'Branch')

    def getInputportMetadata(self):
        return self.get(InputportMetadataDevModel, 'InputportMetadata')

    def isError(self):
        return self.getValue('Error')>0

class NodeDevModel(Node,StaticDevModel):
    def isString(self):
        return self.getValue('IsStr')==1.0

    def getNodeType(self):
        return self.getValue('NodeType')

    def getFormula(self):
        return self.get(FormulaDevModel,'Formula')

    def getCellMetadata(self):
        return self.get(CellMetadataDevModel,'CellMetadata')

    def getNode(self):
        return self.get(NodeDevModel,'Node')

    def getNodeList(self):
        metadataList = self.getList('Node','Node')
        metadataNodeList = [NodeDevModel(obj) for obj in metadataList]
        metadataNodeList.sort(lambda x, y: cmp(x.getArgNo(), y.getArgNo()))
        return metadataNodeList

    def isRootNode(self):
        return self.getValue('Formula') is not None

    def getArgNo(self):
        return self.getValue('ArgNo')

    def getNodeValue(self):
        return self.getValue('Value')

    def isPublicRef(self):
        return self.getValue('IsPublicRef')

    def isNodeParenthesised(self):
        return self.getValue('IsParenthesised')

    def getLeadingWS(self):
        return self.getValue('LeadingWS')

    def getTrailingWS(self):
        return self.getValue('TrailingWS')

    def isError(self):
        return self.getValue('Error')>0

    def getNodeFloatValue(self):
        return self.getValue('NodeFloatValue')

    def isSyntacticSugar(self):
        return self.getValue('IsSyntacticSugar')

class DescendantNodeDevModel(BaseNode, StaticDevModel):
    def __init__(self, dictVal):
        self.synchronous = dictVal.get('synchronous')
        self.refCellMetadata = dictVal.get('refCellMetadata')
        self.nodeType = dictVal.get('nodeType')
        self.cellMetadata = dictVal.get('cellMetadata')

    def getSheetId(self):
        return None

    def getSheetName(self):
        return None

    def getCellMetadata(self):
        return self.cellMetadata

    def getNodeType(self):
        return self.nodeType

    def getReferenceCellMetadata(self):
        return self.refCellMetadata

    def isSynchronous(self):
        if not self.synchronous:
            return False
        if len(self.synchronous) == 0 or self.synchronous.__eq__('true'):
            return True
        if self.synchronous.__eq__('false'):
            return False

class ActivityDefinitionDevModel(ActivityDefinition,StaticDevModel):
    def getActivityDefinitionName(self):
        return self.getValue('SheetName')

    def getSequenceNo(self):
        return self.getValue('SequenceNo')

    def getTaskStatus(self):
        return self.getValue('TaskStatus')

    def getFormulaList(self):
        metadataList = self.getList('ActivityDefinition','Formula')
        return [FormulaDevModel(obj) for obj in metadataList]

    def getBranchList(self):
        metadataList = self.getList('ActivityDefinition','Branch')
        metadataBranchList =  [BranchDevModel(obj) for obj in metadataList]
        metadataBranchList.sort(lambda x, y: cmp(x.getSequenceNo(), y.getSequenceNo()))
        return metadataBranchList

    def getSearchDefinitionList(self):
        metadataList = self.getList('ActivityDefinition','SearchDefinition')
        return [SearchDefinitionDevModel(obj) for obj in metadataList]

    def getBranch(self):
        return self.get(BranchDevModel,'Branch')

    def getGridView(self):
        return self.get(GridViewDevModel,'GridView')

    def containsFormula(self):
        return len(self.getFormulaList())>0

    def getPreviousRef(self):
        return self.get(ActivityDefinitionDevModel,'PreviousRef')

    def getNodeType(self):
        return  self.getValue('NodeType')

    def getAppRole(self):
        return self.getValue('A')

    def isStatic(self):
        return self.getValue('Static')!=0.0

    def getButtonList(self):
        metadataList = self.getList('ActivityDefinition','Button')
        return [ButtonDevModel(obj) for obj in metadataList]

    def getCellMetadata(self):
        return self.get(CellMetadataDevModel,'CellMetadata')

    def getAssignedFor(self):
        return self.getValue('AssignedFor')

    def getGoTo(self):
        return self.get(ActivityDefinitionDevModel,'GoTo')

    def getRoot(self):
        return self.getValue('Root')

    def getProcessType(self):
        return  self.getValue('ProcessType')

    def getAllowedFormulaList(self):
        metadataList = self.getList('AllowedFormula','Formula')
        return [FormulaDevModel(obj) for obj in metadataList]

    def containsAllowedFormula(self):
        return len(self.getAllowedFormulaList())>0 and len(self.getAllowedFormulaList()[0])>0

    def getOutputportMetadataList(self):
        metadataList = self.getList('ActivityDefinition','OutputportMetadata')
        return [OutputportMetadataDevModel(obj) for obj in metadataList]

    def getInputportMetadataList(self):
        metadataList = self.getList('ActivityDefinition','InputportMetadata')
        return [InputportMetadataDevModel(obj) for obj in metadataList]

    def isContinueOnError(self):
        return self.getValue('ContinueOnError')!=0.0

    def getFinalInboxGridView(self):
        gridView = self.get(GridViewDevModel,'FinalInboxGridView')
        if gridView:
            return gridView.getSheetName()

    def getFinalEditorGridView(self):
        gridView = self.get(GridViewDevModel,'FinalEditorGridView')
        if gridView:
            return gridView.getSheetName()

    def getFinalEditorForm(self):
        return self.getValue('FinalEditorForm')

    def getFinalInboxForm(self):
        return self.getValue('FinalInboxForm')

    def getHierarchyList(self):
        metadataList = self.getList('InputActivityDefinition','Hierarchy')
        return [HierarchyDevModel(obj) for obj in metadataList]

    def getOutputHierarchyList(self):
        metadataList = self.getList('OutputActivityDefinition','Hierarchy')
        return [HierarchyDevModel(obj) for obj in metadataList]

    def getBelongingSheetId(self):
        return self.getValue('BelongingSheetId')

    def getActivityTenant(self):
        return self.getValue('ActivityTenant')

    def getAssignedTo(self):
        return self.getValue('AssignedTo')

    def getActivityTenantFormulaList(self):
        metadataList = self.getList('ActivityTenantFormula','Formula')
        return [FormulaDevModel(obj) for obj in metadataList]

    def containsActivityTenantFormula(self):
        return len(self.getActivityTenantFormulaList())>0

class BranchDevModel(Branch,StaticDevModel):
    def getBranchName(self):
        return self.getSheetName()

    def getProcessType(self):
        return self.getValue('ProcessType')

    def getNodeType(self):
        return self.getValue('NodeType')

    def getSequenceNo(self):
        return self.getValue('SequenceNo')

    def getFormulaList(self):
        metadataList = self.getList('Branch','Formula')
        return [FormulaDevModel(obj) for obj in metadataList]

    def getActivityDefinitionList(self):
        metadataList = self.getList('Branch','ActivityDefinition')
        metadataActivityDefinitionList = [ActivityDefinitionDevModel(obj) for obj in metadataList]
        metadataActivityDefinitionList.sort(lambda x, y: cmp(x.getSequenceNo(), y.getSequenceNo()))
        return metadataActivityDefinitionList

    def getActivityDefinition(self):
        return self.get(ActivityDefinitionDevModel,'ActivityDefinition')

    def getSheetMetadata(self):
        return self.get(SheetMetadataDevModel,'SheetMetadata')

    def containsFormula(self):
        return len(self.getFormulaList())>0

    def getRoot(self):
        return self.getValue('Root')

class InputportMetadataDevModel(InputportMetadata, StaticDevModel):

    def getStringValue(self):
        return self.getValue('StringValue')

    def getFloatValue(self):
        return self.getValue('FloatValue')

    def isStr(self):
        return self.getValue('IsStr')

    def getSequenceNo(self):
        return self.getValue('SequenceNo')

    def getActivityDefinition(self):
        return self.get(ActivityDefinitionDevModel, 'ActivityDefinition')

    def getCellMetadata(self):
        return self.get(CellMetadataDevModel, 'CellMetadata')

    def getFormulaList(self):
        metadataList = self.getList('InputportMetadata','Formula')
        return [FormulaDevModel(obj) for obj in metadataList]

    def containsFormula(self):
        return len(self.getFormulaList())>0

    def getParamName(self):
        return self.getValue('ParamName')

    def getHierarchy(self):
        return self.get(HierarchyDevModel, 'Hierarchy')

    def getBranch(self):
        return self.get(BranchDevModel, 'Branch')

    def getActivityDefinitionRef(self):
        return self.get(ActivityDefinitionDevModel, 'ActivityDefinitionRef')


class OutputportMetadataDevModel(OutputportMetadata, StaticDevModel):

    def getCellMetadata(self):
        return self.get(CellMetadataDevModel, 'CellMetadata')

    def getSequenceNo(self):
        return self.getValue('SequenceNo')

    def getActivityDefinition(self):
        return self.get(ActivityDefinitionDevModel, 'ActivityDefinition')

    def getParamName(self):
        return self.getValue('ParamName')

    def getHierarchy(self):
        return self.get('Hierarchy')

class LevelDevModel(Level,StaticDevModel):
    def getLevelName(self):
        return self.getSheetName()

    def getRowNumber(self):
        return self.getValue('RowNumber')

    def getRowHeight(self):
        return self.getValue('RowHeight')

    def getApplication(self):
        return self.get(ApplicationDevModel,'Application')

    def getActivityDefinitionList(self):
        metadataList = self.getList('Level','ActivityDefinition')
        return [ActivityDefinitionDevModel(obj) for obj in metadataList]

class MenuGroupDevModel(MenuGroup,StaticDevModel):
    def getMenuGroupList(self):
       metadataList = self.getList('MenuGroup','MenuGroup')
       return [MenuGroupDevModel(obj) for obj in metadataList]

    def getParentMenuGroup(self):
        return self.get(MenuGroupDevModel,'MenuGroup')

    def getLayoutViewList(self):
        metadataList = self.getList('MenuGroup','LayoutView')
        return [LayoutViewDevModel(obj) for obj in metadataList]

    def getMenuGroupName(self):
        return self.getSheetName()

    def getApplication(self):
        return self.get(ApplicationDevModel,'Application')

class LayoutViewDevModel(LayoutView,StaticDevModel):
    def getApplication(self):
        return self.get(ApplicationDevModel,'Application')

    def getLayoutViewName(self):
        return self.getSheetName()

    def getMenuGroup(self):
        return self.get(MenuGroupDevModel,'MenuGroup')

    def getLayoutRowList(self):
        metadataList = self.getList('LayoutView','LayoutRow')
        return [LayoutRowDevModel(obj) for obj in metadataList]

    def getLayoutColumnList(self):
        metadataList = self.getList('LayoutView','LayoutColumn')
        return [LayoutColumnDevModel(obj) for obj in metadataList]

    def getWidth(self):
        return self.getValue('Width')

class LayoutRowDevModel(LayoutRow,StaticDevModel):
    def getLayoutView(self):
        return self.get(LayoutViewDevModel,'LayoutView')

    def getLayoutCellList(self):
        metadataList = self.getList('LayoutRow','LayoutCell')
        return [LayoutCellDevModel(obj) for obj in metadataList]

    def getRowHeight(self):
        return self.getValue('RowHeight')

    def getRowNumber(self):
        return self.getValue('RowNumber')

class LayoutColumnDevModel(LayoutColumn,StaticDevModel):
    def getLayoutView(self):
        return self.get(LayoutViewDevModel,'LayoutView')

    def getLayoutCellList(self):
        metadataList = self.getList('LayoutColumn','LayoutCell')
        return [LayoutCellDevModel(obj) for obj in metadataList]

    def getColumnWidth(self):
        return self.getValue('ColumnWidth')

    def getColumnNumber(self):
        return self.getValue('ColumnNumber')

    def getColumnName(self):
        return self.getValue('ColumnName')

class LayoutCellDevModel(LayoutCell,StaticDevModel):
    def getLayoutRow(self):
        return self.get(LayoutRowDevModel,'LayoutRow')

    def getRowSpanned(self):
        return self.getValue('RowSpanned')

    def getLayoutColumn(self):
        return self.get(LayoutColumnDevModel,'LayoutColumn')

    def getColumnSpanned(self):
        return self.getValue('ColumnSpanned')

    def getColumnNumber(self):
        return self.getValue('ColumnNUmber')

    def getRowNumber(self):
        return self.getValue('RowNumber')

    def getCellDisplayName(self):
        return self.getValue('CellDisplayName')

    def getActivityDefinitionList(self):
        metadataList = self.getList('LayoutCell','ActivityDefinition')
        return [ActivityDefinitionDevModel(obj) for obj in metadataList]

    def getType(self):
        return self.getValue('Type')

class SearchDefinitionDevModel(SearchDefinition,StaticDevModel):
    def getSearchDefinitionName(self):
        return self.getSheetName()

    def getActivityDefinition(self):
        return self.get(ActivityDefinitionDevModel,'ActivityDefinition')

    def getCellMetadata(self):
        return self.get(CellMetadataDevModel,'CellMetadata')

    def getDisplayCell(self):
        return self.get(CellMetadataDevModel,'DisplayCell')

    def getCriteriaList(self):
        metadataList = self.getList('SearchDefinition','Criteria')
        return [CriteriaDevModel(obj) for obj in metadataList]

    def getItemsPerPage(self):
        return self.getValue('ItemsPerPage')

    def isDefault(self):
        return self.getValue('Default')

    def getTableStyle(self):
        return self.get(TableStyleDevModel,'TableStyle')

    def isNotAllowNone(self):
        return self.getValue('DontAllowNone')

    def isDescending(self):
        return self.getValue('IsDescending')

    def getParentReferenceCell(self):
        return self.get(CellMetadataDevModel,'ParentReferenceCell')

    def getReferredSheetMetadata(self):
        return self.get(SheetMetadataDevModel,'ReferredSheetMetadata')

    def getSearchReferenceCell(self):
        return self.get(CellMetadataDevModel,'SearchReferenceCell')

    def getSheetMetadata(self):
        return self.get(SheetMetadataDevModel, 'SheetMetadata')

    def getFormulaList(self):
        metadataList = self.getList('SearchDefinition','Formula')
        return [FormulaDevModel(obj) for obj in metadataList]

    def containsFormula(self):
        return len(self.getFormulaList())>0

    def getFinalInboxGridView(self):
        gridView = self.get(GridViewDevModel,'FinalInboxGridView')
        if gridView:
            return gridView.getSheetName()

    def getFinalInboxForm(self):
        return self.getValue('FinalInboxForm')

class HeaderDevModel(Header,StaticDevModel):
    def getHeaderName(self):
        return self.getSheetName()

    def getIndex(self):
        return self.getValue('Index')

    def getWidth(self):
        return self.getValue('Width')

    def getOrderBy(self):
        return self.getValue('OrderBy')

    def getCellMetadata(self):
        return self.get(CellMetadataDevModel,'CellMetadata')

    def getHierarchy(self):
        return self.get(HierarchyDevModel,'Hierarchy')

class HierarchyDevModel(Hierarchy,StaticDevModel):
    def getReferenceCell(self):
        return self.get(CellMetadataDevModel,'ReferenceCell')

    def getHierarchyList(self):
        metadataList = self.getList('Hierarchy','Hierarchy')
        return [HierarchyDevModel(obj) for obj in metadataList]

    def getHeaderList(self):
        metadataList = self.getList('Hierarchy','Header')
        return [HeaderDevModel(obj) for obj in metadataList]

    def getActivityDefinition(self):
        return self.get(ActivityDefinitionDevModel,'InputActivityDefinition')

    def getOutputActivityDefinition(self):
        return self.get(ActivityDefinitionDevModel,'OutputActivityDefinition')

    def getNodeName(self):
        return self.getValue('NodeName')

    def getInputportMetadataList(self):
        metadataList = self.getList('Hierarchy', 'InputportMetadata')
        return [InputportMetadataDevModel(obj) for obj in metadataList]

    def getOutputportMetadataList(self):
        metadataList = self.getList('Hierarchy', 'OutputportMetadata')
        return [OutputportMetadataDevModel(obj) for obj in metadataList]

    def getHierarchy(self):
        return self.get(HierarchyDevModel,'Hierarchy')


class SectionDevModel(Section,StaticDevModel):
    def getSectionName(self):
        return self.getSheetName()

    def getFrom(self):
        return self.get(CellMetadataDevModel,'From')

    def getTo(self):
        return self.get(CellMetadataDevModel,'To')

    def getSheetMetadata(self):
        return self.get(SheetMetadataDevModel,'SheetMetadata')

class GridViewDevModel(GridView,StaticDevModel):
    gridRowDict = dict()
    gridColumnDict = dict()

    def getGridViewName(self):
        return self.getSheetName()

    def getSheetMetadata(self):
        return self.get(SheetMetadataDevModel,'SheetMetadata')

    def getGridCell(self):
        return self.get(GridCellDevModel,'GridCell')

    def getGridRowList(self):
        metadataList = self.getList('GridView','GridRow')
        return [GridRowDevModel(obj) for obj in metadataList]

    def getGridColumnList(self):
        metadataList = self.getList('GridView','GridColumn')
        return [GridColumnDevModel(obj) for obj in metadataList]

    def getJSTLString(self):
        return JSTLUtil.getJSTLString_GridView(self,'json')

    def isDefault(self):
        return self.getValue('Default')

    def getProperty(self):
        raise self.getValue('Property')

    def getGridViewHeight(self):
        raise self.getValue('GridViewHeight')

    def getGridViewWidth(self):
        raise self.getValue('GridViewWidth')

class GridRowDevModel(GridRow,StaticDevModel):
    def getRowNumber(self):
        return self.getValue('RowNumber')

    def getRowHeight(self):
        return self.getValue('RowHeight')

    def getStyle(self):
        return self.get(StyleDevModel,'Style')

    def getReferenceCellMetadata(self):
        return self.get(CellMetadataDevModel,'CellMetadata')

    def getGridView(self):
        return self.get(GridViewDevModel,'GridView')

    def getGridCellList(self):
        metadataList = self.getList('GridRow','GridCell')
        return [GridCellDevModel(obj) for obj in metadataList]

    def getFinalHeight(self):
        raise self.getValue('FinalHeight')

class GridColumnDevModel(GridColumn,StaticDevModel):
    def getColumnNumber(self):
        return self.getValue('ColumnNumber')

    def getColumnWidth(self):
        return self.get(ColumnWidthDevModel,'ColumnWidth')

    def getReferenceCellMetadata(self):
        return self.get(ReferenceCellMetadataDevModel,'ReferenceCellMetadata')

    def getGridView(self):
        return self.get(GridViewDevModel,'GridView')

    def getGridCellList(self):
        metadataList = self.getList('GridColumn','GridCell')
        return [GridCellDevModel(obj) for obj in metadataList]

    def getFinalWidth(self):
        raise self.getValue('FinalWidth')

class GridCellDevModel(GridCell,StaticDevModel):
    def getStyle(self):
        return self.get(StyleDevModel,'Style')

    def getRowSpanned(self):
        return self.getValue('RowSpanned')

    def getColumnSpanned(self):
        return self.getValue('ColumnSpanned')

    def getCellValue(self):
        return self.getValue('CellValue')

    def getGridRow(self):
        return self.get(GridRowDevModel,'GridRow')

    def getGridColumn(self):
        return self.get(GridColumnDevModel,'GridColumn')

    def getSection(self):
        return self.get(SectionDevModel,'Section')

    def getCellMetadata(self):
        return self.get(CellMetadataDevModel,'CellMetadata')

    def getGridViewList(self):
        metadataList = self.getList('GridCell','GridView')
        return [GridViewDevModel(obj) for obj in metadataList]

    def getJSTLString(self,sheetMetadataId,jsonName):
        if self.getCellMetadata():
            cellMetdata = self.getCellMetadata()
            startRowNumber = cellMetdata.getRowMetadata().getRowNumber()
            startColumnNumber = cellMetdata.getColumnMetadata().getColumnNumber()
            return JSTLUtil.getJSTLString_CellMetadata(startRowNumber,startColumnNumber,sheetMetadataId,jsonName)
        elif self.getSection():
            section = self.getSection()
            startCell = section.getFrom()
            endCell = section.getTo()
            startRowNumber = startCell.getRowMetadata().getRowNumber()
            endRowNumber = endCell.getRowMetadata().getRowNumber()
            startColumnNumber = startCell.getColumnMetadata().getColumnNumber()
            endColumnNumber = endCell.getColumnMetadata().getColumnNumber()
            return JSTLUtil.getJSTLString_Section(startRowNumber,endRowNumber,startColumnNumber,endColumnNumber,sheetMetadataId,jsonName)
        elif len(self.getGridViewList())>0:
            refGridView = self.getGridViewList().pop()
            return JSTLUtil.getJSTLString_GridView(refGridView,jsonName)
        elif self.getCellValue():
            return JSTLUtil.getJSTLString_CellValue(self)
        else:
            return ""

    def getGridRowSpan(self):
        return GridRowSpanDevModel (self.get('GridRowSpan'))

    def getGridRowSpanList(self):
        metadataList = self.getList('GridCell','GridRowSpan')
        return [GridRowSpanDevModel(obj) for obj in metadataList]

    def getColumnNumber(self):
        return self.getValue('GridColumnNumber')

    def getRowNumber(self):
        return self.getValue('GridRowNumber')

    def isHidden(self):
        return self.getValue('Hidden')

    def getWidgetType(self):
        return self.getValue('WidgetType')

    def getActivityPermissionList(self):
        metadataList = self.getList('GridCell','ActivityPermission')
        return [ActivityPermissionDevModel(obj) for obj in metadataList]

    def getGridViewHeight(self):
        raise self.getValue('GridViewHeight')

    def getGridViewWidth(self):
        raise self.getValue('GridViewWidth')

    def getCriteriaList(self):
        metadataList = self.getList('GridCell','Criteria')
        return [CriteriaDevModel(obj) for obj in metadataList]

    def getPropertyList(self):
        metadataList = self.getList('GridCell','Property')
        return [PropertyDevModel(obj) for obj in metadataList]

    def getHintMessage(self):
        return self.getValue('HintMessage')

    def getErrorMessage(self):
        return self.getValue('ErrorMessage')

    def isRead(self):
        return self.getValue('Read')

    def isWrite(self):
        return self.getValue('Write')

    def isVisible(self):
        return self.getValue('Visible')

class StyleDevModel(Style,StaticDevModel):
    def getStyleName(self):
        return self.getSheetName()

    def getApplication(self):
        return self.get(ApplicationDevModel,'Application')

    def getFontFamily(self):
        return self.getValue('Font_family')

    def getFontWeight(self):
        return self.getValue('Font_weight')

    def getFontSize(self):
        return self.getValue('Font_size')

    def getFontStyle(self):
        return self.getValue('Font_style')

    def getColor(self):
        return self.getValue('Color')

    def getTextAlign(self):
        return self.getValue('Text_align')

    def getTextDecoration(self):
        return self.getValue('Text_decoration')

    def getBorderTop(self):
        return self.getValue('Border_top')

    def getBorderBottom(self):
        return self.getValue('Border_bottom')

    def getBorderLeft(self):
        return self.getValue('Border_left')

    def getBorderRight(self):
        return self.getValue('Border_right')

    def getBorderColor(self):
        return self.getValue('Border_color')

    def getBorderStyle(self):
        return self.getValue('Border_style')

    def getTextIndent(self):
        return self.getValue('Text_indent')

    def getTextTransform(self):
        return self.getValue('Text_transform')

    def getBackgroundColor(self):
        return self.getValue('Background_color')

class RowSpanDevModel(RowSpan,StaticDevModel):
    def getCellMetadata(self):
        return self.get(CellMetadataDevModel,'CellMetadata')

    def getCellMetadataList(self):
        metadataList = self.getList('RowSpan','CellMetadata')
        return [CellMetadataDevModel(obj) for obj in metadataList]

    def getColumnSpanned(self):
        return self.getValue('ColumnSpanned')

class GridRowSpanDevModel(RowSpan,StaticDevModel):
    def getGridCell(self):
        return self.get(GridCellMetadataDevModel,'GridCellMetadata')

    def getGridCellList(self):
        metadataList = self.getList('GridRowSpan','GridCellMetadata')
        return [GridCellMetadataDevModel(obj) for obj in metadataList]

    def getGridColumnSpanned(self):
        return self.getValue('GridColumnSpanned')

class TableStyleDevModel(TableStyle,StaticDevModel):
    def getTableStyleName(self):
        return self.getValue('SheetName')

    def getApplication(self):
         return self.get(ApplicationDevModel,'Application')

    def getCategory(self):
        return  self.getValue('Category')

    def getFirstRowBGColor(self):
        return self.getValue('FirstRowBGcolor')

    def getRowFontStyle(self):
        return self.getValue('RowFontStyle')

    def getRowFontWeight(self):
        return self.getValue('RowFontWeight')

    def getRowFontSize(self):
        return self.getValue('RowFontSize')

    def getRowFontFace(self):
        return self.getValue('RowFontFace')

    def getSecondRowBGColor(self):
        return self.getValue('SecondRowBGcolor')

    def getHeaderBGColor(self):
        return self.getValue('HeaderBGcolor')

    def getHeaderFontColor(self):
        return self.getValue('HeaderFontColor')

    def getHeaderFontStyle(self):
        return self.getValue('HeaderFontStyle')

    def getHeaderFontWeight(self):
        return self.getValue('HeaderFontWeight')

    def getHeaderFontSize(self):
        return self.getValue('HeaderFontSize')

    def getHeaderFontFace(self):
        return self.getValue('HeaderFontFace')

class CriteriaDevModel(Criteria,StaticDevModel):

    def getCriteria(self):
        return self.get(CriteriaDevModel,'Criteria')

    def getCriteriaList(self):
        metadataList = self.getList('Criteria','Criteria')
        return [CriteriaDevModel(obj) for obj in metadataList]

    def getConditionList(self):
        metadataList = self.getList('Criteria','Condition')
        return [ConditionDevModel(obj) for obj in metadataList]

    def isAndOper(self):
        return self.getValue('AndOper')

    def isOrOper(self):
        #used in search execution
        return self.getValue('OrOper')

    def getSearchDefinition(self):
        return self.get(SearchDefinitionDevModel,'SearchDefinition')

    def getGridCell_Read(self):
        return self.get(GridCellDevModel,'GridCell_Read')

    def getGridCell_Write(self):
        return self.get(GridCellDevModel, 'GridCell_Write')

    def getGridCell_Visible(self):
        return self.get(GridCellDevModel, 'GridCell_Visible')

    def getActivityPermission_Read(self):
        return self.get(ActivityPermissionDevModel, 'ActivityPermission_Read')

    def getActivityPermission_Write(self):
        return self.get(ActivityPermissionDevModel, 'ActivityPermission_Write')

    def getActivityPermission_Visible(self):
        return self.get(ActivityPermissionDevModel, 'ActivityPermission_Visible')

class ConditionDevModel(Condition,StaticDevModel):

    def getCriteria(self):
        return self.get(CriteriaDevModel,'Criteria')

    def getRHSFormulaList(self):
        metadataList = self.getList('RHSCondition','Formula')
        return [FormulaDevModel(obj) for obj in metadataList]

    def getLHSFormulaList(self):
        metadataList = self.getList('LHSCondition','Formula')
        return [FormulaDevModel(obj) for obj in metadataList]

    def getOperator(self):
        return self.getValue('Operator')

    def getLHSValue(self):
        return self.getValue('LHSValue')

    def getRHSValue(self):
         return self.getValue('RHSValue')

    def getLHSCellMetadata(self):
        return self.get(CellMetadataDevModel,'LHSCellMetadata')

    def getRHSParentReferenceCellMetadata(self):
        return self.get(CellMetadataDevModel,'RHSParentReferenceCellMetadata')

    def getRHSReferenceCellMetadata(self):
        return self.get(CellMetadataDevModel,'RHSReferenceCellMetadata')

    def getRHSCellMetadata(self):
        return self.get(CellMetadataDevModel,'RHSCellMetadata')

    def getRHSParamType(self):
        return self.getValue('RHSParamType')

    def getSearchDefinition(self):
        return self.get(SearchDefinitionDevModel, 'SearchDefinition')

    def getSearchDefinitionList(self):
        return self.getList('Condition.SearchDefinition')

class LevelRowSpanDevModel(LevelRowSpan,StaticDevModel):
    def getColumnSpanned(self):
        return self.getValue('ColumnSpanned')

class ButtonDevModel(Button,StaticDevModel):
    def getAction(self):
        return self.getValue('Action')

    def getIcon(self):
         return self.getValue('Icon')

    def getSize(self):
        return self.getValue('Size')

    def getGoTo(self):
        return self.getValue('GoTo')

    def getIndex(self):
        return self.getValue('Index')

    def getActivityDefinition(self):
        return self.get(ActivityDefinitionDevModel,'ActivityDefinition')

class ActivityPermissionDevModel(ActivityPermission,StaticDevModel):
    def getGridCell(self):
        return self.get(GridCellDevModel,'GridCell')

    def getActivityDefinition(self):
        return self.get(ActivityDefinitionDevModel,'ActivityDefinition')

    def getCondition(self):
        return self.getValue('Condition')

    def isRead(self):
        return self.getValue('Read')

    def isWrite(self):
        return self.getValue('Write')

    def isVisible(self):
        return self.getValue('Visible')

class PropertyDevModel(Property,StaticDevModel):
    def getGridCell(self):
        return self.get(GridCellDevModel,'GridCell')

    def getAttributeName(self):
        return self.getValue('AttributeName')

    def getStaticValue(self):
        return self.getValue('StaticValue')

    def getFormulaValue(self):
        return self.getValue('FormulaValue')

class RangeDevModel(Range,StaticDevModel):
    def getApplication(self):
        return self.get(ApplicationDevModel,'Application')

    def getRangeList(self):
        metadataList = self.getList('Range','RangeValue')
        return [RangeValueDevModel(obj) for obj in metadataList]

class RangeValueDevModel(RangeValue,StaticDevModel):
    def getValue(self):
        return self.getValue('Value')

    def getRange(self):
        return self.get(RangeDevModel,'Range')

class FolderDevModel(Folder,StaticDevModel):
    def getFolderList(self):
        metadataList = self.getList('Folder','Folder')
        return [FolderDevModel(obj) for obj in metadataList]

    def getSheetMetadataList(self):
        return [obj.getSheetId() for obj in self.getSheetMetadataObjectList()]

    def getSheetMetadataObjectList(self):
        metadataList = self.getList('Folder','SheetMetadata')
        return [SheetMetadataDevModel(obj) for obj in metadataList]

    def getFolder(self):
        return self.get(FolderDevModel,'Folder')

    def getShortCutList(self):
        metadataList = self.getList('Folder','ShortCut')
        return [ShortCutDevModel(obj) for obj in metadataList]

class ShortCutDevModel(ShortCut,StaticDevModel):
    def getFolder(self):
        return self.get(FolderDevModel,'Folder')

    def getSheetMetadata(self):
        return self.get(SheetMetadataDevModel,'SheetMetadata')

    def getGridView(self):
        gridView = self.get(GridViewDevModel,'GridView')
        if gridView:
            return gridView.getSheetName()

    def getBranch(self):
        return self.get(BranchDevModel,'Branch')

