import sqlite3
import xml.etree.ElementTree as ElementTree
import datetime

import database_functions as db
import xml_functions as xml
import terminaltable_functions as ttf



def klemmenplan_erstellen(originFile, rueckmeldungen):
    connection = sqlite3.connect(':memory:')
    # connection = sqlite3.connect('QET.db')
    cursor = connection.cursor()
    db.createSQLiteTable(cursor, connection, rueckmeldungen)

    class Conductor:
        def __init__(self, element1, terminal1, element2, terminal2, function,
                     cable, conductor_section, conductor_color, bus,
                     tension_protocol):
            self.terminal1 = terminal1
            self.element1 = element1
            self.terminal2 = terminal2
            self.element2 = element2
            self.function = function
            self.cable = cable
            self.conductor_section = conductor_section
            self.conductor_color = conductor_color
            self.bus = bus
            self.tension_protocol = tension_protocol
        
    class Terminalstrip:
        def __init__(self,Id, uuid, name, element_typ):
            self.Id = Id
            self.uuid = uuid
            self.name = name
            self.elemen_typ = element_typ
            
    class Terminal:
        def __init__(self, Id, label, terminalstrip, folio, x, y):
            self.Id = Id
            self.label = label
            self.terminalstrip = terminalstrip
            self.folio = folio
            self.x = x
            self.y = y

    class Terminalpoint:
        def __init__(self, terminalstrip, terminal, name, page, x, y, plant,
                     location, element, element_terminalpoint, typ, function,
                     cross_section, cable, conductor_color, bus, tension_protocol):
            self.terminalstrip = terminalstrip
            self.terminal = terminal
            self.name = name
            self.page = page
            self.x = x
            self.y = y
            self.plant = plant
            self.location = location
            self.element = element
            self.element_terminalpoint = element_terminalpoint
            self.typ = typ
            self.function = function
            self.cross_section = cross_section
            self.cable = cable
            self.conductor_color = conductor_color
            self.bus = bus
            self.tension_protocol = tension_protocol
            
    class Bridge:
        def __init__(self,terminal = "", circle = 0, y_start = "245",
                     y_end = "1036", position = "", start = "circle", end = "circle"):
            self.terminal = terminal
            self.circle = circle
            self.y_start = y_start
            self.y_end = y_end
            self.position = position
            self.start = start
            self.end = end

    class Element:
        def __init__(self, uuid, element_name, location,
                     function, strip_label, terminal_label, plant, folio, x, y):
            self.uuid = uuid
            self.element_name = element_name
            self.location = location
            self.function = function
            self.strip_label = strip_label
            self.terminal_label = terminal_label
            self.plant = plant
            self.folio = folio
            self.x = x
            self.y = y
            

    #-------------------------------------------------------------------------------
    # read the original file
    #-------------------------------------------------------------------------------

    #originFile = str(input())
#     originFile = "/home/xander/Nextcloud/ABB_CM-UFD-X.qet"
    # originFile = "/home/xander/Nextcloud/Python/Klemmenplan/Schutz.qet"
    # originFile = "C:/Users/Alexander/Nextcloud/Python/Klemmenplan/Schutz.qet"
    # originFile = "C:/Users/Alexander/Nextcloud/ABB_CM-UFD-X.qet"
    # originFile = "C:/Users/Alexander/Desktop/Verteiler Test.qet"

    xmldoc = xml.parsedoc(originFile, rueckmeldungen)
    xml.collect_conductors(xmldoc, cursor, connection,rueckmeldungen)
    xml.collect_diagramms(xmldoc, cursor, connection, rueckmeldungen)
    xml.collect_elements(xmldoc, cursor, connection, rueckmeldungen)

    xmltree = xml.parsetree(originFile)
    xml.collect_elementTerminals(xmltree, cursor, connection, rueckmeldungen)




    #-------------------------------------------------------------------------------
    # Sorting the elements to terminalstrings, terminals and terminalpoints
    #-------------------------------------------------------------------------------

    print("Sorting the elements into terminalstrips") 
    ruekm = "Die Klemmen werden in die Klemmleiste eingefügt"
    rueckmeldungen(ruekm)
    sql = ("SELECT * FROM elements WHERE label LIKE '-X%'")
    cursor.execute(sql)
    databaseElements = cursor.fetchall()
    db.sorting_terminals(databaseElements, Element, cursor, connection)
    db.setTerminalLocation(cursor, connection)
    print("Sorting the terminalpoints")
    ruekm = ("Die Klemmpunkte werden sortiert")
    rueckmeldungen(ruekm)
    db.sorting_terminalpoints(databaseElements, Element, Conductor, cursor, connection, rueckmeldungen)

    #-------------------------------------------------------------------------------
    # Take the data to write it into the new file
    #-------------------------------------------------------------------------------



    # category wird nur einmal gebraucht, unabhängig von der Anzahl der Klemmleisten
    eTable = xml.createCategory()
    ePage = None 
    eTablePart = None

    diagramTemplate = xml.diagramTemplate(xmltree)
    newDiagramData = xml.newDiagram(xmltree)

    pagenumber = db.noticePagenumber(cursor)
    originPages = pagenumber

    date = datetime.datetime.now().strftime("%Y%m%d")

    # Klemleiste auswählen
    cursor.execute("SELECT * FROM terminalstrips ORDER BY label")

    klemmleisten = cursor.fetchall()
    for klemmleiste in klemmleisten:
        terminalstrip_obj = Terminalstrip(klemmleiste[0], klemmleiste[1],
                                      klemmleiste[2], klemmleiste[3],)
        counter1 = 1
        p = 0
        partcounter = 0
        versatz = 20
        cableList = []

        innerBridge = Bridge(position = "inner")
        outerBridge = Bridge(position = "outer")
        bridge = ""
        
        # Reihenanzahl für die Tabelle ermitteln und klemmenaufbaubezeichnung
        # ermitteln

        cursor.execute(f"""SELECT * FROM embeddedElementTerminals WHERE 
                       element_name IS '{terminalstrip_obj.elemen_typ}'""")
        klemmenaufbau = cursor.fetchall()
        reihenzahl = ttf.number_of_rows(klemmenaufbau)
        klemmpunkteName = ttf.terminalpoints(klemmenaufbau)
        
        #Klemmleisten holen
        cursor.execute(f"""SELECT * FROM terminals WHERE terminalstrip IS
    '{terminalstrip_obj.Id}' ORDER BY label""")
        klemmennummer = cursor.fetchall()
        for klemme in klemmennummer:
            terminal_obj = Terminal(klemme[0], klemme[1], klemme[2], klemme[3], klemme[4],
                                klemme[5])
            cursor.execute(f"""SELECT * FROM terminalpoints WHERE terminalstrip IS
        '{terminalstrip_obj.Id}' AND terminal IS '{terminal_obj.Id}' ORDER BY terminal, name""")
            anschluesse = cursor.fetchall()
            
            # Seiten und Teilabschnitte erstellen
            if counter1 == 1:
                pagenumber += 1 
                partcounter += 1
                parts = int(len(klemmennummer) / (40/reihenzahl))
                if len(klemmennummer) % (40/reihenzahl) > 0:
                    parts +=1
                identstr = xml.createIdent()
                if ePage == None :
                    ePage = xml.createPage(klemmleiste[2], pagenumber - originPages, diagramTemplate, newDiagramData, date, partcounter, identstr)
                else:
                    ePage.append(xml.createPage(klemmleiste[2], pagenumber - originPages, diagramTemplate, newDiagramData, date, partcounter, identstr))
                eTablePart = xml.createTable(klemmleiste[2], partcounter, parts, identstr)           
                print ("Create the sheet")
                ruekm = ("Blatt wird erstellt")
                rueckmeldungen(ruekm)
                
                # Liste mit den verwendeten Kabeln für den jeweiligen Teilabschnitt erstellen

            for anschluss in anschluesse:
                terminalpoint_obj = Terminalpoint(anschluss[0], anschluss[1], anschluss[2],
                                              anschluss[3], anschluss[4], anschluss[5],
                                              anschluss[6], anschluss[7], anschluss[8],
                                              anschluss[9], anschluss[10], anschluss[11],
                                              anschluss[12], anschluss[13], anschluss[14],
                                              anschluss[15], anschluss[16])
                if terminalpoint_obj.cable != "":
                    cableIsInList = False
                    for i in cableList:
                        if terminalpoint_obj.cable in i:
                            cableIsInList = True 
                    if cableIsInList == False:   
                        cableList.append([terminalpoint_obj.cable,
                                          terminalpoint_obj.tension_protocol,
                                          terminalpoint_obj.cross_section,
                                          terminalpoint_obj.plant + " " +
                                          terminalpoint_obj.location] )
                cableList.sort()

            
            # Teilabschnitte mit Daten füllen
            pos = eTablePart.find("definition/description")
            line = xml.createLines(counter1, reihenzahl)
            for i in line.iter("line"):
                pos.append(i)
            for anschluss in anschluesse:
                terminalpoint_obj = Terminalpoint(anschluss[0], anschluss[1], anschluss[2],
                                  anschluss[3], anschluss[4], anschluss[5],
                                  anschluss[6], anschluss[7], anschluss[8],
                                  anschluss[9], anschluss[10], anschluss[11],
                                  anschluss[12], anschluss[13], anschluss[14],
                                  anschluss[15], anschluss[16])
                counter2 = counter1
                func = terminalpoint_obj.function
                pos = eTablePart.find("definition/description")
                if terminalpoint_obj.typ == 'Outer':
                    row = xml.createRowOuter(terminalpoint_obj, counter2, klemmpunkteName, cableList)
                    for i in row.iter("text"):
                        pos.append(i)
                if terminalpoint_obj.typ == 'Inner':
                    row = xml.createRowInner(terminalpoint_obj, counter2, klemmpunkteName, cableList)
                    for i in row.iter("text"):
                        pos.append(i)
                if terminalpoint_obj.typ == 'Generic':
                    if terminalpoint_obj.name.endswith("_a") or \
                    terminalpoint_obj.name.endswith("_o") or \
                    terminalpoint_obj.name.endswith("_l") or \
                    terminalpoint_obj.name.endswith("_e"):
                        bridgepoints = xml.createBridge1(terminalpoint_obj, counter1,reihenzahl)
                        outerBridge.circle += 1
                        if outerBridge.circle == 1:
                            outerBridge.y_start = str(bridgepoints[0])
                            outerBridge.terminal = bridgepoints[2]
                            
                        if outerBridge.circle == 2:
                            if outerBridge.terminal == bridgepoints[2]:
                                outerBridge.circle = 0
                            else:
                                outerBridge.y_end = str(bridgepoints[0])
                                bridge = xml.createBridge2(outerBridge)
                                outerBridge = Bridge(position="outer")
                    if terminalpoint_obj.name.endswith("_b") or \
                       terminalpoint_obj.name.endswith("_r") or \
                    terminalpoint_obj.name.endswith("_i"):
                        bridgepoints = xml.createBridge1(terminalpoint_obj, counter1,reihenzahl)
                        innerBridge.circle += 1
                        if innerBridge.circle == 1:
                            innerBridge.y_start = str(bridgepoints[0])
                            innerBridge.terminal = bridgepoints[2]
                            
                        if innerBridge.circle == 2:
                            if innerBridge.terminal == bridgepoints[2]:
                                innerBridge.circle = 0
                            else:
                                innerBridge.y_end = str(bridgepoints[0])
                                bridge = xml.createBridge2(innerBridge)
                                innerBridge = Bridge(position="inner")
            if bridge != "":
                for i in bridge.iter("line"):
                    pos.append(i)



            terminalnumber = xml.createTerminal(klemme, counter1, reihenzahl,
                                                klemmpunkteName, func)


            for i in terminalnumber.iter("text"):
                pos.append(i) 


                        
     # Mit jeder neuen Klemmenzeile wird x um 40 erhöht, die neue Zeile 
     # 40 punkte tiefer gezeichnet. Bei 40 Zeilen ist das Ende der Seite erreicht
     # und eine neue kann beginnen mit neuer Abschnitts-Nummer
            counter1 += reihenzahl
            if counter1 >= 40:
                cableListPart = xml.createCableListPart(cableList) # Liste mit den verwendeten Kabeln für den Teilabschnitt einfügen
                for i in cableListPart.iter("text"):
                    pos.append(i)
                eTable.insert(2, eTablePart) # Einfügen der Tabelle in die Datei, neue Tabelle bei
                cableList = [] # leeren der Kabelliste des Blattes
                counter1 = 1   # überlauf des Blattes
                if outerBridge.circle == 1:
                    outerBridge.end = "none"
                    bridge = xml.createBridge2(outerBridge)
                    for i in bridge.iter("line"):
                        pos.append(i)
                    outerBridge.end = "circle"
                    outerBridge.y_start = "245"
                    outerBridge.start = "none"
                if innerBridge.circle == 1:
                    innerBridge.end = "none"
                    bridge = xml.createBridge2(innerBridge)
                    for i in bridge.iter("line"):
                        pos.append(i)
                    innerBridge.end = "circle"
                    innerBridge.y_start = "245"
                    innerBridge.start = "none"
                bridge = ""

        if counter1 >1: # Einfügen der Tabelle, nur wenn der Abschnitt auch Klemmen enthält
            cableListPart = xml.createCableListPart(cableList) # Liste mit den verwendeten Kabeln für den Teilabschnitt einfügen
            for i in cableListPart.iter("text"):
                pos.append(i)
            eTable.insert(2, eTablePart)

    ec = xmltree.find("collection/category")
    ed = xmltree.getroot()
                    
    ec.insert(4, eTable)
    ed.insert(5, ePage)

    #--------------------------------------------------------------------------------
    # Übergabe zur Datei ... put fata to file
    #--------------------------------------------------------------------------------
    saveFile = originFile.replace(".qet", "_terminals.qet")

    ElementTree.indent(xmltree, space='    ', level=0)
    xmltree.write(saveFile, encoding='UTF-8' , xml_declaration=None , default_namespace= None , method='xml', short_empty_elements=False)
    
    print("Finished!")
    ruekm = ("\nFertig!\nDie Datei wurde unter\n" + saveFile + "\ngespeichert.")
    rueckmeldungen(ruekm)
