#!/usr/bin/python
from PySide import QtSvg, QtXml
from PySide.QtCore import QLocale, QFile, QIODevice
from PySide.QtGui import *
import json

#
# Main
#

if __name__ == "__main__":
    import sys

    doc = QtXml.QDomDocument("doc")

    # Load a JSON file containing initial parameters for each device.
    deviceList="./ui/Sharknir/deviceList.json"
    f=open(deviceList,"r")
    devices=json.load(f)
    f.close()

    file = QFile("shark_syn_panel.svg")
    #file = QFile("shark_syn_metro.svg")
    if not file.open(QIODevice.ReadOnly):
        print("Cannot open the svg file")
        exit(-1)

    if not doc.setContent(file):
        print("Cannot parse the content");
        file.close()
        exit(-1)
        file.close()

    roots = doc.elementsByTagName("svg")
    if roots.size() < 1:
        print("Cannot find root")
        exit(-1)

    def findByKeyVal(propList,key,val) :
        listOfProps = next((p for p in propList if p[key] == val), None)
        return listOfProps

    def propsById(propList,val) :
        return findByKeyVal(propList,"id",val)

    def getNodeAttrName(node, nodeAttr) :
        return node.attributes().namedItem(nodeAttr).nodeValue()

    def getNodeId(node) :
        return getNodeAttrName(node,"id")

    def setText(node,val) :
        node.firstChild().setNodeValue(str(val))
        return node

    def findByNodeAttrName(nodeType, nodeAttr, nodeValue) :
        nodes = doc.elementsByTagName(nodeType)
        for n in range(nodes.length()) :
            node = nodes.at(n).toElement()
            nodeName = node.attribute(nodeAttr)
            if nodeName == nodeValue :
                #print("found "+nodeValue)
                return node

    def findByNodeId(nodeType, nodeId) :
        return findByNodeAttrName(nodeType,"id",nodeId)

    def findPath(nodeId) :
        return findByNodeId("path", nodeId)

    def findDevice(nodeId) :
        return findByNodeId("g", nodeId)

    def findText(nodeId) :
        return findByNodeId("text", nodeId)

    def isOn(nodeId) :
        on=findPath(nodeId).attribute("on")
        try : return int(on)
        except : print(nodeId+" 'on' attribute is not int: "+on)

    def toggleDisplay(nodeId, visible=True) :
        dev=findDevice(nodeId)
        dev.setAttribute("style", "display:inline") if visible else dev.setAttribute("style", "display:none")
        return nodeId

    def setPosition(nodeId, position) :
        dev=findDevice(nodeId)
        childs=dev.childNodes()
        for c in range(childs.length()) :
            dev=childs.at(c).toElement()
            childNodeId=getNodeId(dev)
            toggleDisplay(childNodeId, c==position)
        return childNodeId

    def switchPath(nodeId, switchOn=True) :
        path = findPath(nodeId)
        path.setAttribute("on",switchOn)  # also set a new attribute to retrieve status
        if switchOn :
            #path.setAttribute("stroke", "#ff6600")
            path.setAttribute("stroke", "#bb0000")
        else :
            path.setAttribute("stroke", "#666666")
        return switchOn

    def switchDevice(deviceName, position) :
        '''Changes the device status
        @param deviceName device id as in json file
        @param position required position
        '''

        def inbeam_dep():
            switchPath("light-in",  position)
            switchPath("light-ext", not position)
            return

        def shutter():
            if isOn("light-in") :
                switchPath("light-shutter", position)
            return

        def fiber_lamps():
            switchPath("light-lamps-0",  position)
            switchPath("light-lamps-1",  position)
            return

        def ff_lamp():
            switchPath("light-ff",  position)
            return

        def fiber_dep():
            if isOn("light-lamps-0") and position==1 :
                switchPath("light-fiber-0", position)
            if isOn("light-lamps-1") and position==2 :
                switchPath("light-fiber-1", position)
            return

        def filter_dep():
            if isOn("light-ff") :
                switchPath("light-filter", position)
            return

        def mirror_dep():
            if isOn("light-shutter") and position==False :
                switchPath("light-general", not position)
                return
            if isOn("light-filter") and position==True :
                switchPath("light-general", position)
                return
            if isOn("light-fiber-0") or isOn("light-fiber-1") and position==True :
                switchPath("light-general", position)
                return

        def lens_dep():
            return

        # Map the inputs to the function blocks.
        options = {
            # "id in json file": funct_name
            "INBEAM_DEP" :     inbeam_dep,
            "SHUTTER" :        shutter,
            "CAL_FIBER_LAMPS": fiber_lamps,
            "CAL_FF_LAMP" :    ff_lamp,
            "CAL_FIBER_DEP" :  fiber_dep,
            "CAL_FILTER_DEP" : filter_dep,
            "CAL_MIRROR_DEP" : mirror_dep,
            "PUPIL_LENS_DEP" : lens_dep,
        }

        iconId = propsById(devices,deviceName)["icon"] # Retrieve the icon id in svg file
        setPosition(iconId, position)  # Set the device in the right position
        result = options[deviceName]() # Call the draw function.

    switchDevice("INBEAM_DEP", True)
    switchDevice("SHUTTER", False)

    # switchDevice("CAL_FIBER_FOCUS_LAMP", True)
    # switchDevice("CAL_FIBER_DEFOCUS_LAMP", True)
    switchDevice("CAL_FF_LAMP", False)

    switchDevice("CAL_FIBER_DEP", 2) # 0 1 2
    switchDevice("CAL_FILTER_DEP", False)

    switchDevice("CAL_MIRROR_DEP", True)
    switchDevice("PUPIL_LENS_DEP", True)

    # Change values taking from json defaults.
    for d in devices :
        textVal=findText(d["value"])

        if "INBEAM_TT" not in d["id"] :
            default= d[d["default"]] if (d.has_key("abs")) else d["default"]
        else :
            default= d[d["default_x"]] if (d.has_key("abs_x")) else d["default_x"]
            
        setText(textVal, default)

    app = QApplication(sys.argv)
    svgWidget = QtSvg.QSvgWidget()
    svgWidget.load(doc.toByteArray())
    svgWidget.setWindowTitle("SHARK Synoptic Panel")
    svgWidget.show()

    sys.exit(app.exec_())
