
'''
    NOTES:
    # All of the fields in forceTitleFields must be in forceOutFields but not vice versa
'''

# import cElementTree as ElementTreepythoin turn xml to dictionary

import json
import re
import xml.etree.ElementTree as ElementTree

def etree_to_dict(t):
    d = {t.tag : map(etree_to_dict, t.getchildren())}
    d.update(('@' + k, v) for k, v in t.attrib.iteritems())
    d['text'] = t.text
    return d

def digIdentify(step,dict,parentName):
    
    thisName = ''
    
    if 'ApplicationSettings' in dict: thisName = 'ApplicationSettings'
    if 'IdentifyLayers' in dict: thisName = 'IdentifyLayers'
    
    if ( thisName == 'ApplicationSettings' ):
        
        for i in range(len(dict[thisName])):
            
            digIdentify(0,dict[thisName][i],thisName)
            
    
    if ( thisName == 'IdentifyLayers' ):
        
        for i in range(len(dict[thisName])):
            
            if thisName == 'IdentifyLayers':
                
                contents = digIdentify(0,dict[thisName][i],thisName)
                
                if contents['type'] != 'divider': identifylayers_ref[contents['url']] = contents
                
                identifylayers.append(contents)
                
                
    if 'SummaryFields' in dict:
        
        newSummaryFields = {'SummaryFields':[]}
        
        for i in range(len(dict['SummaryFields'])):
            
            newField = {}
            newField['name'] = ''
            newField['title'] = ''
            
            if '@Name' in dict['SummaryFields'][i]: newField['name'] = dict['SummaryFields'][i]['@Name']
            if '@Title' in dict['SummaryFields'][i]: newField['title'] = dict['SummaryFields'][i]['@Title']
            
            newSummaryFields['SummaryFields'].append(newField)
            
            # newSummaryFields['attributes'].append(newField)
            
            # newSummaryFields['SummaryFields']['name'] = newField['name']
            # newSummaryFields['SummaryFields']['title'] = newField['title']
        
        return newSummaryFields
    
    
    if 'DetailFields' in dict:
        
        newDetailFields = {'DetailFields':[]}
        
        for i in range(len(dict['DetailFields'])):
            
            newField = {}
            newField['name'] = ''
            newField['title'] = ''
            
            if '@Name' in dict['DetailFields'][i]: newField['name'] = dict['DetailFields'][i]['@Name']
            if '@Title' in dict['DetailFields'][i]: newField['title'] = dict['DetailFields'][i]['@Title']
            
            # newDetailFields['DetailFields']['name'] = newField['name']
            # newDetailFields['DetailFields']['title'] = newField['title']
            
            newDetailFields['DetailFields'].append(newField)
        
        return newDetailFields
    
    if 'Layer' in dict:
        
        if ( parentName == 'IdentifyLayers' ):
            
            # print json.dumps(dict, indent=4, sort_keys=True)
            
            newLayer = {'name':'','type':'','url':'','layerIds':[],'canexport':True,'DetailFields':[],'SummaryFields':[]}
            
            if '@Url' in dict: 
                
                if dict['@Url'] != 'None':
                
                    newLayer['url'] = dict['@Url'] # + '/' + dict['@LayerIndex']
                    newLayer['url'] = newLayer['url'].replace('//', '/')
                    
                    if '@LayerIndex' in dict:               
                        newLayer['layerIds'] = [int(dict['@LayerIndex'])]
                    else:
                        newLayer['layerIds'] = [0]
                                        
                    newLayer['type'] = 'layer'
                    
                else:
                    
                    newLayer['type'] = 'divider'
            
            
            # SummaryFields & DetailFields
            for i in range(len(dict['Layer'])):
                
                # substitute fields for forced fields defined in this script
                
                if newLayer['url'] in forceTitleFields:
                    newLayer['SummaryFields'] = forceTitleFields[newLayer['url']]
                else:                                    
                    FieldArray = digIdentify(0,dict['Layer'][i],parentName)                    
                    if 'SummaryFields' in dict['Layer'][i]: newLayer['SummaryFields'] = FieldArray['SummaryFields'] 
                
                if newLayer['url'] in forceOutFields:    
                    newLayer['DetailFields'] = forceOutFields[newLayer['url']]                    
                else:                                    
                    FieldArray = digIdentify(0,dict['Layer'][i],parentName)                                
                    if 'DetailFields' in dict['Layer'][i]: newLayer['DetailFields'] = FieldArray['DetailFields']
            
            
            if '@Name' in dict: 
                
                newName = dict['@Name'].replace("-", "").strip()
                
                newLayer['name'] = newName
                
                
            if '@CanExport' in dict: 
                
                if dict['@CanExport'] == 'false': newLayer['canexport'] = False
                
            
            return newLayer
                
            # print json.dumps(dict, indent=4, sort_keys=True)
            # print json.dumps(newLayer, indent=4, sort_keys=True)
    

def digGroup(step,dict,parentName):
    
    thisName = ''
    
    if 'ApplicationSettings' in dict: thisName = 'ApplicationSettings'
    if 'LegendLayers' in dict: thisName = 'LegendLayers'
    if 'SecureLegendLayers' in dict: thisName = 'SecureLegendLayers'
    if 'LayerGroup' in dict: thisName = 'LayerGroup'
    
    if ( thisName == 'ApplicationSettings' ) or ( thisName == 'LegendLayers' ) or ( thisName == 'SecureLegendLayers' ):
        
        for i in range(len(dict[thisName])):
            
            contents = digGroup(0,dict[thisName][i],thisName)
            
            if thisName == 'LegendLayers': legendlayers.append(contents)
            
            if thisName == 'SecureLegendLayers': securelegendlayers.append(contents)
    
    if 'LayerGroup' in dict:
        
        if ( parentName == 'LegendLayers' ) or ( parentName == 'SecureLegendLayers' ):
            
            # debug #            
            # print 'LayerGroup: <' + str(parentName) + '>' + str(group)
            
            newGroup = {}
            newGroup['type'] = 'group'
            newGroup['id'] = str(dict['@Name'])
            newGroup['attributes'] = []
            
            for i in range(len(dict['LayerGroup'])): 
                
                newGroup['attributes'].append(digGroup(0,dict['LayerGroup'][i],parentName))
                
            return newGroup
    
    if 'Layer' in dict:
        
        if ( parentName == 'LegendLayers' ) or ( parentName == 'SecureLegendLayers' ):
        
            id = 0
            newLayer = {}
            
            newLayer['type'] = 'layer'
            newLayer['id'] = ''
            newLayer['attributes'] = {}
            newLayer['attributes']['url'] = ''
            newLayer['attributes']['visibleonstart'] = False
            newLayer['attributes']['showdetails'] = False
            newLayer['attributes']['hasLabels'] = False
            newLayer['attributes']['layerlist'] = True
            newLayer['attributes']['mapvisible'] = True
            newLayer['attributes']['canbuffer'] = False
            newLayer['attributes']['canidentify'] = False
            newLayer['attributes']['sumfield'] = ''
            newLayer['attributes']['outFields'] = []#'*'
            newLayer['attributes']['titleFields'] = []
            newLayer['attributes']['dynamic'] = False
            newLayer['attributes']['visibleLayers'] = []
            
            # layer id
            if 'Layer' in dict: id = str(dict['Layer'][0]['@ID'])
            
            # layer url
            if '@Url' in dict:
                
                newLayer['attributes']['url'] = str(dict['@Url'] + '/' + id)
                
                if '@Type' in dict:
                    if str(dict['@Type']) == 'ArcGISDynamicMapServiceLayer':
                        newLayer['attributes']['url'] = str(dict['@Url'])
                        newLayer['attributes']['visibleLayers'] = [id]
                        newLayer['attributes']['dynamic'] = True
                        
                newLayer['attributes']['url'] = newLayer['attributes']['url'].replace('//', '/')
                
                for s in range(len(invisibleLayers)):                
                    if newLayer['attributes']['url'] == invisibleLayers[s]:                    
                        newLayer['attributes']['mapvisible'] = False
                
            # title name
            if '@Name' in dict: newLayer['id'] = str(dict['@Name'])
            
            # visibility on start
            if '@Visible' in dict:
                if str(dict['@Visible']) == 'False': newLayer['attributes']['visibleonstart'] = False
                else: newLayer['attributes']['visibleonstart'] = True
            else :
                newLayer['attributes']['visibleonstart'] = False
            
            # buffer tool availability
            if '@CanBuffer' in dict:
                if str(dict['@CanBuffer']) == 'False': newLayer['attributes']['canbuffer'] = False
                else: newLayer['attributes']['canbuffer'] = True
            else:
                newLayer['attributes']['canbuffer'] = False
                        
            # aggregate tool availability
            if ( '@SumField' in dict ) and ( dict['@SumField'] != 'none' ):                    
                newLayer['attributes']['sumfield'] = str(dict['@SumField'])
                newLayer['attributes']['mapvisible'] = False
                
            # process identify attributes. the identifylayers array must be ready for this to work
            
            if newLayer['attributes']['url'] in identifylayers_ref: 
                
                newLayer['attributes']['canidentify'] = True
                
                identifyValues = identifylayers_ref[newLayer['attributes']['url']]['DetailFields']                
                if len(identifyValues) > 0:

                    newOutFields = []
                    for a in range(len(identifyValues)):                        
                        try: 
                            newOutFields.append(identifyValues[a]['name'])
                        except: 
                            newOutFields.append(identifyValues[a])
                    
                    # newLayer['attributes']['outFields'] = newOutFields
                    
                
                identifyValues = identifylayers_ref[newLayer['attributes']['url']]['SummaryFields']                
                if len(identifyValues) > 0:
                    
                    newTitleFields = []
                    for a in range(len(identifyValues)): 
                        try:
                            newTitleFields.append(identifyValues[a]['name'])
                        except:
                            newTitleFields.append(identifyValues[a])

                    
                    newLayer['attributes']['titleFields'] = newTitleFields

                
                    
            return newLayer
            
            # debug #        
            # print '---layer-start---'
            # for key in dict: print '- ' + key + ' : ' + str(dict[key])
            # print '---layer-end---'



parentName = ''

legendlayers = []
securelegendlayers = []
identifylayers = []
identifylayers_ref = {}

replaceAttr = ["attributes","canbuffer","hasLabels","layerlist","mapvisible","outFields","showdetails","sumfield","titleFields","url","visibleonstart","id","type","name","title","canexport","fields","DetailFields","SummaryFields","canidentify","layerIds","dynamic","visibleLayers"]

# List of layers that should be invisible in the map
# To add a layer, include the layer's url: ie. "WVRHA/PrimaryCareWorkforce/MapServer/3"
invisibleLayers = []

# All of the fields in forceTitleFields must be in forceOutFields but not vice versa
forceTitleFields = {
        "WVRHA/BaseLayers/MapServer/3":["NAMELSAD10","popdens","rural","PhysTot"],
        "WVRHA/WV_updates_1/MapServer/0":["Of_name"]
    }    

forceOutFields = {
        "WVRHA/BaseLayers/MapServer/3":[{"name": "NAMELSAD10","title": "NAMELSAD10"},{"name": "popdens","title": "popdens"},{"name": "rural","title": "rural"}],
        "WVRHA/WV_updates_1/MapServer/0":[{"name": "Of_name","title": "Of_name"}]
    }

print 'Loading template...'

with open('layers_template.txt', 'r') as template: templateData = template.read()

print 'Done.'

print 'Converting xml...'

# Get xml file - convert to dictionary
tree = ElementTree.parse('settings.xml')
root = tree.getroot()
xmldict = etree_to_dict(root)

print 'Done.'

print 'Gathering data...'

digIdentify(0,xmldict,parentName)

digGroup(0,xmldict,parentName)

print 'Done.'

print 'Comparing arrays...'



print 'Done.'

print 'Generating layers javascript...'

# Legend Layers #
legendlayers_result = json.dumps(legendlayers, indent=4, sort_keys=True)
for i in range(len(replaceAttr)): legendlayers_result = legendlayers_result.replace('"' + replaceAttr[i] + '"', replaceAttr[i])
templateData = templateData.replace('{layer_groups}', legendlayers_result)

# Secure Legend Layers #
securelegendlayers_result = json.dumps(securelegendlayers, indent=4, sort_keys=True)
for i in range(len(replaceAttr)): securelegendlayers_result = securelegendlayers_result.replace('"' + replaceAttr[i] + '"', replaceAttr[i])
templateData = templateData.replace('{secure_layer_groups}', securelegendlayers_result)

# Identify Layers #
identifylayers_result = json.dumps(identifylayers, indent=4, sort_keys=True)
for i in range(len(replaceAttr)): identifylayers_result = identifylayers_result.replace('"' + replaceAttr[i] + '"', replaceAttr[i])
templateData = templateData.replace('{identify_layers}', identifylayers_result)

target = open('layers_lists.js', 'w')
target.truncate()

target.write(templateData)

print 'Done.'

print 'All Done.'

print json.dumps(identifylayers_ref, indent=4, sort_keys=True)

# print templateData

'''
{
    type : 'group',
    id : '___GroupID___',
    attributes : [
        {
            type : 'layer',
            id : '___LayerID___',
            attributes : {
                url : '',
                visibleonstart : false,
                showdetails : false,
                hasLabels : false,
                layerlist : true,
                mapvisible : true,
                canbuffer : true,
                sumfield : '',
                outFields : ['*'],
                titleFields : [],
            }
        },
    ]
}
'''
