# -*- coding: utf-8 -*-
__author__ = 'TUMCIVIL'
__version__ = '2.0.0'
__title__ = 'เซ็ตระดับหลังคาน\nชนท้องหน้าต่าง'
__doc__ = """Created by : TUMCIVIL TEAM
Version : 2.0.0 
Update : วันที่ 03-03-2025
_________________________________________________________________
รายการ :
เซ็ตระดับหลังคาน(ทับหลัง)ชนท้องหน้าต่าง
_________________________________________________________________
ข้อจำกัดการใช้งาน :
1.ไม่สามารถใช้กับคานที่ Slope ได้
2.ไม่สามารถใช้กับคานที่สร้างจาก Model In-Place ได้
_________________________________________________________________
วิธีการใช้ :
1.เลือกหน้าต่างหลัก
2.เลือกคานที่ต้องการเช็ตระดับหลังคานชนท้องหน้าต่าง
3.ต้องการเลิกทำรายการกด Esc

 """
# for timing -------------------------------------------------------------------
# import pyrevit.coreutils as cor
# from pyrevit.coreutils import Timer
# timer = Timer()
# ------------------------------------------------------------------------------
import sys
import re
import Autodesk
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import *
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB.Structure import *
from Autodesk.Revit.DB.Structure import Rebar as rb
import pyrevit

import  os
from pyrevit import forms, revit
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB import (BuiltInParameter)

#>>>>>>>>>> .NET IMPORTS
import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("System")
from System.Collections.Generic import List
from System.Windows.Controls import ComboBoxItem
import wpf
from Autodesk.Revit.UI.Selection    import ISelectionFilter, ObjectType, Selection

#>>>>>>>>>> CUSTOM IMPORTS
from Snippets._convert_units import convert_internal_units
from Snippets._level import levels,get_levels_walls,get_levels_columns,get_levels_doors,get_levels_windows
from Snippets._level import *
from Selection._select_element import CustomISelectionFilter, pick_column
from System.Collections.ObjectModel import ObservableCollection
from System.ComponentModel import INotifyPropertyChanged


doc   = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument
app   = __revit__.Application

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

#>>>>>>>>> LIMIT SELECTION
class CustomISelectionFilter(ISelectionFilter):
    """Filter user selection to certain element."""
    def __init__(self, cats):
        self.cats = cats
    def AllowElement(self, e):
        if str(e.Category.Id) == str(self.cats):
        #if e.Category.Name == "Walls"
            return True
        return False

class ISelectionFilter_Classes(ISelectionFilter):
    def __init__(self, allowed_types):
        """ ISelectionFilter made to filter with types
        :param allowed_types: list of allowed Types"""
        self.allowed_types = allowed_types

    def AllowElement(self, element):
        if type(element) in self.allowed_types:
            return True
        # else:
        #     return False

#>>>>>>>>>> PICK COLUMN
def pick_beam(given_uidoc = uidoc,text = ""):
    """Function to promt user to select a column element in Revit UI."""
    beam_ref = given_uidoc.Selection.PickObject(ObjectType.Element, CustomISelectionFilter("-2001320"), text)    # -2001320 <- Id of OST_StructuralFraming
    beam     = given_uidoc.Document.GetElement(beam_ref)
    # print("TYPE BEAM = {}".format(type(beam)))
    return beam
def pick_column(given_uidoc = uidoc,text = "เลือกเสา" ):
    """Function to promt user to select a column element in Revit UI."""
    # forms.WarningBar(title='Select Walls.')
    column_ref = given_uidoc.Selection.PickObject(ObjectType.Element, CustomISelectionFilter("-2001330"), text)    # -2001330 <- Id of OST_StructuralColumns
    column     = given_uidoc.Document.GetElement(column_ref)
    return column

def pick_door(given_uidoc = uidoc,text = ""):
    """Function to promt user to select a column element in Revit UI."""
    door_ref = given_uidoc.Selection.PickObject(ObjectType.Element, CustomISelectionFilter("-2000023"), text)    # -2001320 <- Id of OST_StructuralFraming
    door     = given_uidoc.Document.GetElement(door_ref)
    # print("TYPE BEAM = {}".format(type(beam)))
    return door

def pick_window(given_uidoc = uidoc,text = ""):
    """Function to promt user to select a column element in Revit UI."""
    window_ref = given_uidoc.Selection.PickObject(ObjectType.Element, CustomISelectionFilter("-2000014"), text)    # -2001320 <- Id of OST_StructuralFraming
    window     = given_uidoc.Document.GetElement(window_ref)
    # print("TYPE BEAM = {}".format(type(beam)))
    return window



if __name__ == '__main__':

    levels_model = levels()
    # print("levels_model = {}".format(levels_model))

    try:    Selected_window = pick_window(uidoc,"เลือกหน้าต่างตัวหลัก")
    except: forms.alert("Script is canceled.",exitscript=True,title="Script Canceled.")

    if Selected_window.Category.Id.IntegerValue == int(BuiltInCategory.OST_Windows):
        Main_levels_window = get_levels_windows(levels_model,Selected_window)
        Main_Top_elevation = Main_levels_window[1]
        Main_Bottom_elevation = Main_levels_window[0]

        

    # >>>>>>>>>> LOOP: SELECT MATCH BEAM
    with forms.WarningBar(title="เลือกคานที่ต้องการเช็ตค่า (ออกกด Esc):", handle_esc=True):
        while True:

            #>>>>>>>>>> PICK BEAM
            try:    Match_beam = pick_beam(uidoc,"เลือกคานที่ต้องการเช็ตค่า (ออกกด Esc)")
            except: break
            if not Match_beam: break
            Match_base_elev = Match_beam.get_Parameter(BuiltInParameter.STRUCTURAL_ELEVATION_AT_BOTTOM).AsDouble()
            Match_top_elev = Match_beam.get_Parameter(BuiltInParameter.STRUCTURAL_ELEVATION_AT_TOP).AsDouble()
            Match_Z_offset = Match_beam.get_Parameter(BuiltInParameter.Z_OFFSET_VALUE).AsDouble()

            # if 
            Match_Z_offset_adj = Match_Z_offset+(Main_Bottom_elevation-Match_top_elev)

            # print("Match_base_elev = {} ".format(convert_internal_units(Match_base_elev, False,units='mm')))
            # print("Match_top_elev = {} ".format(convert_internal_units(Match_top_elev, False,units='mm')))
            # print("Match_Z_offset = {} ".format(convert_internal_units(Match_Z_offset, False,units='mm')))
            # print("Match_Z_offset_adj = {} ".format(convert_internal_units(Match_Z_offset_adj, False,units='mm')))

            #>>>>>>>>>> SET PARAMETERS
            t = Transaction(doc, 'change parameter')
            t.Start()
            try:
                Match_beam.get_Parameter(BuiltInParameter.Z_OFFSET_VALUE).Set(Match_Z_offset_adj)
            except:
                pass
            t.Commit()



# for timing -------------------------------------------------------------------
# print("====" * 20)
# endtime = timer.get_time()
# print("Time been used = {} sec.".format(endtime))
# currentDate = cor.current_date()
# currentTime = cor.current_time()
# print ("Date : {} ; {}".format(currentDate,currentTime))
# print ("Credited by : {}".format(__author__))
# print("====" * 20)
# ------------------------------------------------------------------------------