# -*- coding: utf-8 -*-
# IMPORTS
# ==================================================
import Autodesk
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import *
import Autodesk.Revit.DB as DB
import pyrevit

# >>>>>>>>>> CUSTOM IMPORTS
from Snippets._convert_units import convert_internal_units

# VARIABLES
# ==================================================
doc   = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument
app      = __revit__.Application
rvt_year = int(app.VersionNumber)

# FUNCTIONS
# ==================================================
def levels():
    levels = DB.FilteredElementCollector(doc).OfCategory(DB.BuiltInCategory.OST_Levels) \
        .WhereElementIsNotElementType() \
        .ToElements()
    # l = len(levels)
    out = []
    for e in levels:
        p =[]
        name = e.get_Parameter(BuiltInParameter.DATUM_TEXT).AsString()
        eleLev = e.get_Parameter(BuiltInParameter.LEVEL_ELEV).AsDouble()
        id = e.Id
        p.append(name)
        p.append(eleLev)
        p.append(id)

        out.append(p)
    # print("out = {}".format(out))
    return out


def checkParameter(parameter):
    storageType = parameter.StorageType
    if (storageType.ToString() == "ElementId"):
        value = parameter.AsValueString()
    return value

def get_levels_walls(levels_model,e):
    try:
        baseLev = e.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT)
        value1 = checkParameter(baseLev)
        baseOff = e.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET).AsDouble()
        # print("baseLev = {} ,baseOff = {}".format(value1,baseOff))
        eleBase = [v[1]+baseOff for v in levels_model if v[0].upper() == value1.strip("Up to level:").upper()]
        # print("eleBase = {}".format(eleBase))
        # for i in eleBase:
        #     eleBaseConvert = UnitUtils.ConvertFromInternalUnits(i,UnitTypeId.Millimeters)
        # # print("eleBaseConvert = {}".format(eleBaseConvert)) 
        # if eleBaseConvert >= 0:
        #     eleBaseCombine = "+"+str(round(eleBaseConvert,0)).replace(".0","")
        #     # eleBaseCombine = "EL.+"+str(round(eleBaseConvert,0)).replace(".0","")
        # elif eleBaseConvert < 0:
        #     eleBaseCombine = str(round(eleBaseConvert,0)).replace(".0","")
    except:
        pass
        # eleBaseCombine = None
            # eleBaseCombine = "EL."+str(round(eleBaseConvert,0)).replace(".0","")
        # print("eleBaseCombine = {}".format(eleBaseCombine))

    try:
        topLev = e.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE)
        value2 = checkParameter(topLev)
        if value2 == "Unconnected":
            value2 = value1
            unconHeight = e.get_Parameter(BuiltInParameter.WALL_USER_HEIGHT_PARAM).AsDouble()
            eleTop = [v[1]+unconHeight+baseOff for v in levels_model if v[0].upper() == value2.strip("Up to level:").upper()]
            # print("eleTop1 = {}".format(eleTop))
            # for i in eleTop:
            #     eleTopConvert = UnitUtils.ConvertFromInternalUnits(i,UnitTypeId.Millimeters)
            # # print("eleTopConvert = {}".format(eleTopConvert)) 
            # if eleTopConvert >= 0:
            #     eleTopCombine = "+"+str(round(eleTopConvert,0)).replace(".0","")
            #     # eleTopCombine = "EL.+"+str(round(eleTopConvert,0)).replace(".0","")
            # elif eleTopConvert < 0:
            #     eleTopCombine = str(round(eleTopConvert,0)).replace(".0","")
            #     eleTopCombine = "EL."+str(round(eleTopConvert,0)).replace(".0","")
        else:
            topOff = e.get_Parameter(BuiltInParameter.WALL_TOP_OFFSET).AsDouble()
            eleTop = [v[1]+topOff for v in levels_model if v[0].upper() == value2.strip("Up to level:").upper()]
            # print("eleTop2 = {}".format(eleTop))

            # for i in eleTop:
            #     eleTopConvert = UnitUtils.ConvertFromInternalUnits(i,UnitTypeId.Millimeters)
            # # print("eleTopConvert = {}".format(eleTopConvert)) 
            # if eleTopConvert >= 0:
            #     eleTopCombine = "+"+str(round(eleTopConvert,0)).replace(".0","")
            #     # eleTopCombine = "EL.+"+str(round(eleTopConvert,0)).replace(".0","")
            # elif eleTopConvert < 0:
            #     eleTopCombine = str(round(eleTopConvert,0)).replace(".0","")
            #     eleTopCombine = "EL."+str(round(eleTopConvert,0)).replace(".0","")
    except:
        pass
        # eleTopCombine = None
    return eleBase[0],eleTop[0]

def get_levels_columns(levels_model,e):
    try:
        baseLev = e.get_Parameter(BuiltInParameter.SCHEDULE_BASE_LEVEL_PARAM)
        value1 = checkParameter(baseLev)
        baseOff = e.get_Parameter(BuiltInParameter.SCHEDULE_BASE_LEVEL_OFFSET_PARAM).AsDouble()
        # print("baseLev = {} ,baseOff = {}".format(value1,baseOff))
        eleBase = [v[1]+baseOff for v in levels_model if v[0].upper() == value1.strip("Up to level:").upper()]
        # print("eleBase = {}".format(eleBase))
        # for i in eleBase:
        #     eleBaseConvert = UnitUtils.ConvertFromInternalUnits(i,UnitTypeId.Millimeters)
        # # print("eleBaseConvert = {}".format(eleBaseConvert)) 
        # if eleBaseConvert >= 0:
        #     eleBaseCombine = "+"+str(round(eleBaseConvert)).replace(".0","")
        #     # eleBaseCombine = "EL.+"+str(round(eleBaseConvert)).replace(".0","")
        # elif eleBaseConvert < 0:
        #     eleBaseCombine = str(round(eleBaseConvert)).replace(".0","")
            # eleBaseCombine = "EL."+str(round(eleBaseConvert)).replace(".0","")
        # print("eleBaseCombine = {}".format(eleBaseCombine))
    except:
        pass
        # eleBaseCombine = None
    try:
        topLev = e.get_Parameter(BuiltInParameter.SCHEDULE_TOP_LEVEL_PARAM)
        value2 = checkParameter(topLev)
        topOff = e.get_Parameter(BuiltInParameter.SCHEDULE_TOP_LEVEL_OFFSET_PARAM).AsDouble()
        # print("topLevs = {} ,topOff = {}".format(value2,topOff))
        eleTop = [v[1]+topOff for v in levels_model if v[0].upper() == value2.strip("Up to level:").upper()]
        # print("eleTop = {}".format(eleTop))
        # for i in eleTop:
        #     eleTopConvert = UnitUtils.ConvertFromInternalUnits(i,UnitTypeId.Millimeters)
        # # print("eleTopConvert = {}".format(eleTopConvert)) 
        # if eleTopConvert >= 0:
        #     eleTopCombine = "+"+str(round(eleTopConvert)).replace(".0","")
        #     # eleTopCombine = "EL.+"+str(round(eleTopConvert)).replace(".0","")
        # elif eleTopConvert < 0:
        #     eleTopCombine = str(round(eleTopConvert)).replace(".0","")
        #     # eleTopCombine = "EL."+str(round(eleTopConvert)).replace(".0","")
    except:
        pass
        # eleTopCombine = None
    return eleBase[0],eleTop[0]


def get_levels_ceilings(levels_model,e):
    try:
        Ceiling_Level     = e.get_Parameter(BuiltInParameter.SCHEDULE_LEVEL_PARAM)
        value1 = checkParameter(Ceiling_Level)
        Height_Offset  = e.get_Parameter(BuiltInParameter.CEILING_HEIGHTABOVELEVEL_PARAM).AsDouble()
        eleCeiling = [v[1]+Height_Offset for v in levels_model if v[0].upper() == value1.strip("Up to level:").upper()]
    except:
        pass
        # eleTopCombine = None
    return eleCeiling[0]

def get_levels_doors(levels_model,e):
    try:
        baseLev = e.get_Parameter(BuiltInParameter.SCHEDULE_LEVEL_PARAM)
        value1 = checkParameter(baseLev)
        baseOff = e.get_Parameter(BuiltInParameter.INSTANCE_SILL_HEIGHT_PARAM).AsDouble()
        # eleBase = [v[1]+ for v in levels_model if v[0].upper() == value1.strip("Up to level:").upper()]
        eleBase = [v[1]+baseOff for v in levels_model if v[0].upper() == value1.strip("Up to level:").upper()]
    except:
        pass
    # print("baseLev = {} ,baseOff = {}".format(value1,baseOff))
    # print("eleBase = {} ".format(convert_internal_units(eleBase[0], False,units='mm')))
    for i in levels_model:
            if value1 == i[0]  :
                Main_bse_Level_value =i[1]
                Main_bse_Level =i[2]
    try:
        head_Height = e.get_Parameter(BuiltInParameter.INSTANCE_HEAD_HEIGHT_PARAM).AsDouble()
        eleTop = Main_bse_Level_value+head_Height

        # print("eleTop = {} ".format(convert_internal_units(eleTop, False,units='mm')))
    except:
        pass
        # eleTopCombine = None
    return eleBase[0],eleTop

def get_levels_windows(levels_model,e):
    try:
        baseLev = e.get_Parameter(BuiltInParameter.SCHEDULE_LEVEL_PARAM)
        value1 = checkParameter(baseLev)
        baseOff = e.get_Parameter(BuiltInParameter.INSTANCE_SILL_HEIGHT_PARAM).AsDouble()
        eleBase = [v[1]+baseOff for v in levels_model if v[0].upper() == value1.strip("Up to level:").upper()]
    except:
        pass
    # print("baseLev = {} ,baseOff = {}".format(value1,baseOff))
    # print("eleBase = {} ".format(convert_internal_units(eleBase[0], False,units='mm')))
    for i in levels_model:
            if value1 == i[0]  :
                Main_bse_Level_value =i[1]
                Main_bse_Level =i[2]
    try:
        # value2 = checkParameter(topLev)
        head_Height = e.get_Parameter(BuiltInParameter.INSTANCE_HEAD_HEIGHT_PARAM).AsDouble()
        eleTop = Main_bse_Level_value+head_Height
        # print("eleTop = {} ".format(convert_internal_units(eleTop, False,units='mm')))
    except:
        pass
        # eleTopCombine = None
    return eleBase[0],eleTop





















# ╔═╗╔╗ ╔═╗╔═╗╦  ╔═╗╔╦╗╔═╗
# ║ ║╠╩╗╚═╗║ ║║  ║╣  ║ ║╣
# ╚═╝╚═╝╚═╝╚═╝╩═╝╚═╝ ╩ ╚═╝ OBSOLETE ( still need to refactor the code)
def convert_cm_to_feet(length):
    """Function to convert cm to feet."""

    # RVT >= 2022
    if rvt_year < 2022:
        from Autodesk.Revit.DB import DisplayUnitType
        return UnitUtils.Convert(length,
                                DisplayUnitType.DUT_CENTIMETERS,
                                DisplayUnitType.DUT_DECIMAL_FEET)
    # RVT >= 2022
    else:
        from Autodesk.Revit.DB import UnitTypeId
        return UnitUtils.ConvertToInternalUnits(length, UnitTypeId.Centimeters)

def convert_m_to_feet(length):
    """Function to convert cm to feet."""

    # RVT >= 2022
    if rvt_year < 2022:
        from Autodesk.Revit.DB import DisplayUnitType
        return UnitUtils.Convert(length,
                                 DisplayUnitType.DUT_METERS,
                                 DisplayUnitType.DUT_DECIMAL_FEET)
    # RVT >= 2022
    else:
        from Autodesk.Revit.DB import UnitTypeId
        return UnitUtils.ConvertToInternalUnits(length, UnitTypeId.Meters)



def convert_internal_to_m(length):
    """Function to convert internal to meters."""

    # RVT >= 2022
    if rvt_year < 2022:
        from Autodesk.Revit.DB import DisplayUnitType
        return UnitUtils.Convert(length,
                                 DisplayUnitType.DUT_DECIMAL_FEET,
                                 DisplayUnitType.DUT_METERS)
    # RVT >= 2022
    else:
        from Autodesk.Revit.DB import UnitTypeId
        return UnitUtils.ConvertFromInternalUnits(length, UnitTypeId.Meters)



def convert_internal_to_cm(length):
    """Function to convert internal to centimeters."""

    # RVT >= 2022
    if rvt_year < 2022:
        from Autodesk.Revit.DB import DisplayUnitType
        return UnitUtils.Convert(length,
                                 DisplayUnitType.DUT_DECIMAL_FEET,
                                 DisplayUnitType.DUT_CENTIMETERS)
    # RVT >= 2022
    else:
        from Autodesk.Revit.DB import UnitTypeId
        return UnitUtils.ConvertFromInternalUnits(length, UnitTypeId.Centimeters)




def convert_internal_to_m2(area):
    """Function to convert internal to meters."""

    # RVT >= 2022
    if rvt_year < 2022:
        from Autodesk.Revit.DB import DisplayUnitType
        return UnitUtils.Convert(area,
                                 DisplayUnitType.DUT_SQUARE_FEET,
                                 DisplayUnitType.DUT_SQUARE_METERS)
    # RVT >= 2022
    else:
        from Autodesk.Revit.DB import UnitTypeId
        return UnitUtils.ConvertFromInternalUnits(area, UnitTypeId.SquareMeters)