import rhinoscriptsyntax as rs
import json
import scriptcontext
import Rhino.Geometry as rg
import Rhino
import System
appendPolyline = []


__commandname__ = "GiraffeImport"

# RunCommand is the called when the user enters the command name in Rhino.
# The command name is defined by the filname minus "_cmd.py"
def RunCommand( is_interactive ):
    
    doc = """splits giraffe payload into model and app data, merges featureCategories into giraffeModel features for ease of use

"""

    path = rs.OpenFileName('input giraffe model path')
    print path
    with open(path,'r') as f:
        json_string = f.read()
    raw_json = json.loads(json_string)
    features_list = raw_json["features"]
    propertieslist = [] 
    valuelist = []
    props = []
    geomlist =[]
    propsList = []

    filtered_feats = [item for item in features_list if "_projected" in item and item["_projected"] and 'type' in item['properties'] and item['properties']['type']]

    layer_names = []
    
    for feature in filtered_feats:
        layer_name = feature['properties']['layerId']
        if layer_name not in layer_names:
            layer_names.append("giraffe "+layer_name)
            
            
    layer_dict = {} # dictionary to store layer name and index
    for layer_name in layer_names:
        
        # print layer_name
        layer_index = scriptcontext.doc.Layers.Add(layer_name,System.Drawing.Color.Black)
        layer_dict[layer_name] = layer_index


    print layer_dict

    layer_names = rs.LayerNames()
    for item in filtered_feats:
        geomlist = []
        try:
            type = item['geometry']['type'] 

            coordinates = item['_projected']
        except:
            type = 'Polygon'
            coordinates = item['geometry']
        if type=="Point":
#            print coordinates
            geomlist.append(rs.AddPoint(coordinates[0],coordinates[1]))
#            print geomlist
        elif (type == "Polygon" or type == "Polyline"):
            if item['properties']['type'] == "buildingSection":
                baseHeight = item['properties']['_baseHeight']
                height = item['properties']['_height']
                color = hex_to_rgb(item['properties']['color'])
                geomlist.append([(coord[0],coord[1],baseHeight) for coord in coordinates[0]])
                points =  [rs.coerce3dpoint(p) for p in geomlist[0]]
                pl = rg.Polyline(points)
                plc = rg.Polyline.ToPolylineCurve(pl)
                
                if abs(height - baseHeight) < 1e-6:
                    print("skipping zero-height buildingSection: " + str(item['properties'].get('usage','')))
                    continue
                try:
                    extru = rg.Surface.CreateExtrusion(plc,rg.Vector3d(0,0,height-baseHeight))
                    if extru is None:
                        print("skipping buildingSection - could not extrude")
                        continue
                    extru = extru.ToBrep()
                    if extru is None:
                        print("skipping buildingSection - ToBrep failed")
                        continue
                    extru = extru.CapPlanarHoles(0.1)
                except:
                    print(plc)
                    continue
                
                color = System.Drawing.Color.FromArgb(color[0],color[1],color[2])
                attr = Rhino.DocObjects.ObjectAttributes()
                attr.ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject
                attr.ObjectColor = color
                attr.Name = item['properties']['usage']
                
                layer_name = 'giraffe '+item['properties']['layerId']
                layer_names = rs.LayerNames()
                print 'layers'
                print layer_names
                print layer_name
                try:
                    layer_index = layer_names.index(layer_name)
                except ValueError:
                    print( layer_name + " not found, assigning default layer index 0")
                    layer_index = 0  
                attr.LayerIndex = layer_index
                try:
                    scriptcontext.doc.Objects.Add(extru,attr)
                except:
                    print(extru)
                
                try:
                    for i in range(item['properties']['levels']):
                        geomlist = []
                        geomlist.append([(coord[0],coord[1],i*item['properties']['floorToFloor']+baseHeight) for coord in coordinates[0]])
                        points =  [rs.coerce3dpoint(p) for p in geomlist[0]]
                        pl = rg.Polyline(points)
                        plc = rg.Polyline.ToPolylineCurve(pl)
                        scriptcontext.doc.Objects.Add(plc,attr)
                        # print i
                except:
                    print item
            elif item['properties']['type'] == "landscape":
                baseHeight = item['properties']['_baseHeight']
                height = item['properties']['_height']
                color = hex_to_rgb(item['properties']['color'])
                geomlist.append([(coord[0],coord[1],baseHeight) for coord in coordinates[0]])
                points =  [rs.coerce3dpoint(p) for p in geomlist[0]]
                pl = rg.Polyline(points)
                plc = rg.Polyline.ToPolylineCurve(pl)
                
                if abs(height - baseHeight) < 1e-6:
                    print("skipping zero-height landscape feature: " + str(item['properties'].get('usage','')))
                    continue
                extru = rg.Surface.CreateExtrusion(plc,rg.Vector3d(0,0,height-baseHeight))
                if extru is None:
                    print("skipping landscape feature - could not extrude: " + str(item['properties'].get('usage','')))
                    continue
                extru = extru.ToBrep()
                if extru is None:
                    print("skipping landscape feature - ToBrep failed: " + str(item['properties'].get('usage','')))
                    continue
                extru = extru.CapPlanarHoles(0.1)
                
                color = System.Drawing.Color.FromArgb(color[0],color[1],color[2])
                attr = Rhino.DocObjects.ObjectAttributes()
                attr.ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject
                attr.ObjectColor = color
                attr.Name = item['properties']['usage']
                layer_name = 'giraffe '+item['properties']['layerId']
                layer_names = rs.LayerNames()
                layer_index = layer_names.index(layer_name)
                
                
                #print layer_dict
                #print layer_dict['giraffe '+item['properties']['layerId']]
                attr.LayerIndex = layer_index
                
                scriptcontext.doc.Objects.Add(extru,attr)                   
            elif item['properties']['type'] == "building":
                baseHeight = item['properties']['_baseHeight']
                height = item['properties']['_height']
                color = hex_to_rgb(item['properties']['color'])
                geomlist.append([(coord[0],coord[1],baseHeight) for coord in coordinates[0]])
                points =  [rs.coerce3dpoint(p) for p in geomlist[0]]
                pl = rg.Polyline(points)
                plc = rg.Polyline.ToPolylineCurve(pl)
                
                if abs(height - baseHeight) < 1e-6:
                    print("skipping zero-height building feature: " + str(item['properties'].get('usage','')))
                    continue
                extru = rg.Surface.CreateExtrusion(plc,rg.Vector3d(0,0,height-baseHeight))
                if extru is None:
                    print("skipping building feature - could not extrude: " + str(item['properties'].get('usage','')))
                    continue
                extru = extru.ToBrep()
                if extru is None:
                    print("skipping building feature - ToBrep failed: " + str(item['properties'].get('usage','')))
                    continue
                extru = extru.CapPlanarHoles(0.1)
                
                color = System.Drawing.Color.FromArgb(color[0],color[1],color[2])
                attr = Rhino.DocObjects.ObjectAttributes()
                attr.ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject
                attr.ObjectColor = color
                layer_name = 'giraffe '+item['properties']['layerId']
                layer_names = rs.LayerNames()
                layer_index = layer_names.index(layer_name)
                
                
                #print layer_dict
                #print layer_dict['giraffe '+item['properties']['layerId']]
                attr.LayerIndex = layer_index
                
                scriptcontext.doc.Objects.Add(extru,attr)
                    

#            rs.SetUserText(curve,
        elif (type == "LineString"):
            geomlist = []
            geomlist.append([(coord[0],coord[1]) for coord in coordinates])
            rs.AddPolyline(geomlist[0])
        elif (type == "MultiLineString"):
            geomlist.append([rs.AddPoint(coord[0],coord[1]) for coord in coordinates[0]])
        try:#properties
            
            properties=item['properties']

            propsList.append(properties)

            propertieslist.append(properties)
            value = []
            for prop in properties:
                item_value = item['properties'][prop]
                value.append(item_value)
            valuelist.append(value)
        except KeyError: 
            properties = "<null>"
            propertieslist.append(properties)
        props.append(json.dumps(properties))
    return {
            "geomlist":geomlist,
            "key":propertieslist, #on convert to list, gh just passes keys
            "value":valuelist,
            "props":props
            }





def PointToRhinoPoint(coordinates):
    if len(coordinates) > 2:
        z = coordinates[2]
    else:
        z = 0.0
    x, y = coordinates[0], coordinates[1]
    return rs.AddPoint(x, y, z)

def MultiPointToRhinoPoint(coordinates):
    rhPointList = []
    for point in coordinates:
        rhPointList.append(PointToRhinoPoint(point))
    return rhPointList

def hex_to_rgb(value):
    try:
        value = value.lstrip('#')
        lv = len(value)
        return tuple(int(value[i:i + lv // 3], 16) for i in range(0, lv, lv // 3))
    except:
        return [255,0,0]


RunCommand(True)