from ply import lex
from ply import yacc
from DNAData import DNAData
from DNAGroup import DNAGroup
from DNAVisGroup import DNAVisGroup
from DNAProp import DNAProp
from DNASign import DNASign
from DNASignBaseline import DNASignBaseline
from DNASignText import DNASignText
from DNASignGraphic import DNASignGraphic
from DNANode import DNANode
from DNALandmarkBuilding import DNALandmarkBuilding
from DNADoor import DNADoor
from DNAFlatDoor import DNAFlatDoor
from DNAFlatBuilding import DNAFlatBuilding
from DNAWall import DNAWall
from DNAStreet import DNAStreet
from DNAWindows import DNAWindows
from DNACornice import DNACornice

tokens = [
  'FLOAT',
  'INTEGER',
  'UNQUOTED_STRING',
  'QUOTED_STRING'
]
reserved = {
  'store_suit_point' : 'STORE_SUIT_POINT',
  'group' : 'GROUP',
  'visgroup' : 'VISGROUP',
  'vis' : 'VIS',
  'STREET_POINT' : 'STREET_POINT',
  'FRONT_DOOR_POINT' : 'FRONT_DOOR_POINT',
  'SIDE_DOOR_POINT' : 'SIDE_DOOR_POINT',
  'COGHQ_IN_POINT' : 'COGHQ_IN_POINT',
  'COGHQ_OUT_POINT' : 'COGHQ_OUT_POINT',
  'suit_edge' : 'SUIT_EDGE',
  'battle_cell' : 'BATTLE_CELL',
  'prop' : 'PROP',
  'pos' : 'POS',
  'hpr' : 'HPR',
  'scale' : 'SCALE',
  'code' : 'CODE',
  'color' : 'COLOR',
  'model' : 'MODEL',
  'store_node' : 'STORE_NODE',
  'sign' : 'SIGN',
  'baseline' : 'BASELINE',
  'width' : 'WIDTH',
  'height' : 'HEIGHT',
  'stomp' : 'STOMP',
  'stumble' : 'STUMBLE',
  'indent' : 'INDENT',
  'wiggle' : 'WIGGLE',
  'kern' : 'KERN',
  'text' : 'TEXT',
  'letters' : 'LETTERS',
  'store_font' : 'STORE_FONT',
  'flat_building' : 'FLAT_BUILDING',
  'wall' : 'WALL',
  'windows' : 'WINDOWS',
  'count' : 'COUNT',
  'cornice' : 'CORNICE',
  'landmark_building' : 'LANDMARK_BUILDING',
  'title' : 'TITLE',
  'article' : 'ARTICLE',
  'building_type' : 'BUILDING_TYPE',
  'door' : 'DOOR',
  'store_texture' : 'STORE_TEXTURE',
  'street' : 'STREET',
  'texture' : 'TEXTURE',
  'graphic' : 'GRAPHIC',
  'hood_model' : 'HOODMODEL',
  'place_model' : 'PLACEMODEL',
  'nhpr' : 'NHPR',
  'flags' : 'FLAGS',
  'node' : 'NODE',
  'flat_door' : 'FLAT_DOOR',
  'anim' : 'ANIM',
  'cell_id' : 'CELL_ID',
  'anim_prop' : 'ANIM_PROP',
  'interactive_prop' : 'INTERACTIVE_PROP',
  'anim_building' : 'ANIM_BUILDING',
}
tokens += reserved.values()
t_ignore = ' \t'

literals = '[],'

def t_ignore_COMMENT(t):
    pass
t_ignore_COMMENT.__doc__ = r'[/]{2,2}.*'

def t_ignore_ML_COMMENT(t):
    pass
t_ignore_ML_COMMENT.__doc__ = r'\/\*([^*]|[\r\n])*\*/'

def t_QUOTED_STRING(t):
    t.value = t.value[1:-1]
    return t
t_QUOTED_STRING.__doc__ = r'["][^"]*["]'

def t_FLOAT(t):
    t.value = float(t.value)
    return t
t_FLOAT.__doc__ = r'[+-]?\d+[.]\d*([e][+-]\d+)?'

def t_INTEGER(t):
    t.value = int(t.value)
    return t
t_INTEGER.__doc__ = r'[+-]?\d+'

def t_UNQUOTED_STRING(t):
    if t.value in reserved:
        t.type = reserved[t.value]
    return t
t_UNQUOTED_STRING.__doc__ = r'[^ \t\n\r\[\],"]+'

def t_newline(t):
    t.lexer.lineno += len(t.value)
t_newline.__doc__ = r'\n+'

def t_error(t):
    print 'Illegal character %s' % t.value[0]
    t.lexer.skip(1)

# Build the lex
lex.lex()

# dictionary of names
names = { }

def p_dna(p):
    pass
p_dna.__doc__ = \
    '''dna : dna object
           | object'''

def p_object(p):
    p[0] = p[1]
p_object.__doc__ = \
    '''object : suitpoint
              | group
              | model
              | font
              | store_texture'''

def p_number(p):
    p[0] = p[1]
p_number.__doc__ = \
    '''number : FLOAT
              | INTEGER'''

def p_lpoint3f(p):
    from panda3d.core import *
    p[0] = LVector3f(p[1], p[2], p[3])
p_lpoint3f.__doc__ = '''lpoint3f : number number number'''

def p_suitpoint(p):
    p.parser.dnaStore.storeSuitPoint(DNASuitPoint(p[3], p[5], p[7]))
p_suitpoint.__doc__ = \
    '''suitpoint : STORE_SUIT_POINT "[" number "," suitpointtype "," lpoint3f "]"
                 | STORE_SUIT_POINT "[" number "," suitpointtype "," lpoint3f "," number "]"''' #last # is landmark building index

def p_suitpointtype(p):
    p[0] = DNASuitPoint.pointTypeMap[p[1]]
p_suitpointtype.__doc__ = \
    '''suitpointtype : STREET_POINT
                     | FRONT_DOOR_POINT
                     | SIDE_DOOR_POINT
                     | COGHQ_IN_POINT
                     | COGHQ_OUT_POINT'''

def p_string(p):
    p[0] = p[1]
p_string.__doc__ = \
    '''string : QUOTED_STRING
              | UNQUOTED_STRING'''

def p_dnagroupdef(p):
    p[0] = DNAGroup(p[2])
    p.parser.parentGroup.add(p[0])
    p[0].setParent(p.parser.parentGroup)
    p.parser.parentGroup = p[0]
p_dnagroupdef.__doc__ = '''dnagroupdef : GROUP string'''

def p_dnanodedef(p):
    p[0] = DNANode(p[2])
    p.parser.parentGroup.add(p[0])
    p[0].setParent(p.parser.parentGroup)
    p.parser.parentGroup = p[0]
p_dnanodedef.__doc__ = '''dnanodedef : NODE string'''

def p_visgroupdef(p):
    p[0] = DNAVisGroup(p[2])
    p.parser.parentGroup.add(p[0])
    p[0].setParent(p.parser.parentGroup)
    p.parser.parentGroup = p[0]
p_visgroupdef.__doc__ = '''visgroupdef : VISGROUP string'''

def p_dnagroup(p):
    p[0] = p[1]
    p.parser.parentGroup = p[0].getParent()
p_dnagroup.__doc__ = '''dnagroup : dnagroupdef "[" subgroup_list "]"'''

def p_visgroup(p):
    p[0] = p[1]
    p.parser.parentGroup = p[0].getParent()
p_visgroup.__doc__ = '''visgroup : visgroupdef "[" subvisgroup_list "]"'''

def p_string_opt_list(p):
    if len(p) == 2:
        p[0] = []
    if len(p) == 3 and not p[2] is None:
        p[0] = p[1]
        p[0] += [p[2]]
p_string_opt_list.__doc__ = \
    '''string_opt_list : string_opt_list string
                       | empty'''

def p_vis(p):
    p.parser.parentGroup.addVisible(p[3])
    for vis in p[4]:
        p.parser.parentGroup.addVisible(vis)
p_vis.__doc__ = '''vis : VIS "[" string string_opt_list "]"'''

def p_empty(p):
    pass
p_empty.__doc__ = \
    '''empty : '''

def p_group(p):
    p[0] = p[1]
p_group.__doc__ = \
    '''group : dnagroup
             | visgroup
             | dnanode
             | windows
             | cornice
             | door'''

def p_dnanode(p):
    p[0] = p[1]
p_dnanode.__doc__ = \
    '''dnanode : prop
               | sign
               | signbaseline
               | signtext
               | flatbuilding
               | wall
               | landmarkbuilding
               | street
               | signgraphic
               | dnanode_grp'''

def p_dnanode_grp(p):
    p[0] = p[1]
    p.parser.parentGroup = p[0].getParent()
p_dnanode_grp.__doc__ = '''dnanode_grp : dnanodedef "[" subdnanode_list "]"'''

def p_sign(p):
    p[0] = p[1]
    p.parser.parentGroup = p[0].getParent()
p_sign.__doc__ = '''sign : signdef "[" subprop_list "]"'''

def p_signgraphic(p):
    p[0] = p[1]
    p.parser.parentGroup = p[0].getParent()
p_signgraphic.__doc__ = '''signgraphic : signgraphicdef "[" subsigngraphic_list "]"'''

def p_prop(p):
    p[0] = p[1]
    p.parser.parentGroup = p[0].getParent()
p_prop.__doc__ = \
    '''prop : propdef "[" subprop_list "]"
            | animpropdef "[" subanimprop_list "]"
            | interactivepropdef "[" subinteractiveprop_list "]"'''

def p_signbaseline(p):
    p[0] = p[1]
    p.parser.parentGroup = p[0].getParent()
p_signbaseline.__doc__ = '''signbaseline : baselinedef "[" subbaseline_list "]"'''

def p_signtest(p):
    p[0] = p[1]
    p.parser.parentGroup = p[0].getParent()
p_signtest.__doc__ = '''signtext : signtextdef "[" subtext_list "]"'''
    
def p_flatbuilding(p):
    p[0] = p[1]
    p.parser.parentGroup = p[0].getParent()
p_flatbuilding.__doc__ = '''flatbuilding : flatbuildingdef "[" subflatbuilding_list "]"'''

def p_wall(p):
    p[0] = p[1]
    p.parser.parentGroup = p[0].getParent()
p_wall.__doc__ = '''wall : walldef "[" subwall_list "]"'''

def p_windows(p):
    p[0] = p[1]
    p.parser.parentGroup = p[0].getParent()
p_windows.__doc__ = '''windows : windowsdef "[" subwindows_list "]"'''

def p_cornice(p):
    p[0] = p[1]
    p.parser.parentGroup = p[0].getParent()
p_cornice.__doc__ = '''cornice : cornicedef "[" subcornice_list "]"'''

def p_landmarkbuilding(p):
    p[0] = p[1]
    p.parser.parentGroup = p[0].getParent()
p_landmarkbuilding.__doc__ = '''landmarkbuilding : landmarkbuildingdef "[" sublandmarkbuilding_list "]"
                                                 | animbuildingdef "[" subanimbuilding_list "]"'''

def p_street(p):
    p[0] = p[1]
    p.parser.parentGroup = p[0].getParent()
p_street.__doc__ = '''street : streetdef "[" substreet_list "]"'''

def p_door(p):
    p[0] = p[1]
    p.parser.parentGroup = p[0].getParent()
p_door.__doc__ = \
    '''door : doordef "[" subdoor_list "]"
            | flatdoordef "[" subdoor_list "]"'''

def p_propdef(p):
    p[0] = DNAProp(p[2])
    p.parser.parentGroup.add(p[0])
    p[0].setParent(p.parser.parentGroup)
    p.parser.parentGroup = p[0]
p_propdef.__doc__ = '''propdef : PROP string'''

def p_animpropdef(p):
    p[0] = DNAAnimProp(p[2])
    p.parser.parentGroup.add(p[0])
    p[0].setParent(p.parser.parentGroup)
    p.parser.parentGroup = p[0]
p_animpropdef.__doc__ = '''animpropdef : ANIM_PROP string'''

def p_interactivepropdef(p):
    p[0] = DNAInteractiveProp(p[2])
    p[0] = DNAInteractiveProp(p[2])
    p.parser.parentGroup.add(p[0])
    p[0].setParent(p.parser.parentGroup)
    p.parser.parentGroup = p[0]
p_interactivepropdef.__doc__ = '''interactivepropdef : INTERACTIVE_PROP string'''

def p_flatbuildingdef(p):
    p[0] = DNAFlatBuilding(p[2])
    p.parser.parentGroup.add(p[0])
    p[0].setParent(p.parser.parentGroup)
    p.parser.parentGroup = p[0]
p_flatbuildingdef.__doc__ = '''flatbuildingdef : FLAT_BUILDING string'''

def p_walldef(p):
    p[0] = DNAWall('')
    p.parser.parentGroup.add(p[0])
    p[0].setParent(p.parser.parentGroup)
    p.parser.parentGroup = p[0]
p_walldef.__doc__ = '''walldef : WALL'''

def p_windowsdef(p):
    p[0] = DNAWindows('')
    p.parser.parentGroup.add(p[0])
    p[0].setParent(p.parser.parentGroup)
    p.parser.parentGroup = p[0]
p_windowsdef.__doc__ = '''windowsdef : WINDOWS'''

def p_cornicedef(p):
    p[0] = DNACornice('')
    p.parser.parentGroup.add(p[0])
    p[0].setParent(p.parser.parentGroup)
    p.parser.parentGroup = p[0]
p_cornicedef.__doc__ = '''cornicedef : CORNICE'''

def p_landmarkbuildingdef(p):
    p[0] = DNALandmarkBuilding(p[2])
    p.parser.parentGroup.add(p[0])
    p[0].setParent(p.parser.parentGroup)
    p.parser.parentGroup = p[0]