#!/usr/bin/python
"""
    This module is a GUI front end for demonstrating the PDK utility Python scripts
    and managing the individual deployment states.
    
    Screen:
    platform detected                                          deployment states
                    Title                                       listed below
                                                                buttons to
                                                                run/display scripts
                    
                    Current deployment state
                    pause button    quit button
                    
                    Script output scroll box
                    
    ~40 rows x 7 columns using the grid geometry manager
"""

__author__ = 'Todd C Davis'
__Product__ = 'Intel_PDK'

from Tkinter import *
import tkMessageBox
from ScrolledText import *
from threading import Timer, Event, Lock
import os, os.path, sys
from deploymentData import *

class PDKdemo(Frame):
    if sys.platform == 'linux2':
        # position lists - [row,column,rowspan,columnspan]
        platformPosition =     [0,4,1,1]
        titlePosition =        [1,0,4,3]
        statePosition =        [5,0,4,3]
        pausePosition =        [9,0,1,1]
        quitPosition =         [9,2,1,1]
        detailPosition =       [10,0,20,3]
        detailButtonPosition = [13,5,1,1]
        statesPosition =       [0,5,1,2]
        # row start positions for demoState objects
        stateLabelPosition =   [2,5,1,2]
        stateShowPosition =    [3,5,1,1]
        stateRunPosition =     [3,6,1,1]
    else:
        # position lists - [row,column,rowspan,columnspan]
        platformPosition =     [0,4,1,1]
        titlePosition =        [1,0,7,3]
        statePosition =        [8,0,7,3]
        pausePosition =        [15,0,1,1]
        quitPosition =         [15,2,1,1]
        detailPosition =       [16,0,20,3]
        detailButtonPosition = [19,5,1,1]
        statesPosition =       [0,5,1,2]
        # row start positions for demoState objects
        stateLabelPosition =   [2,5,1,2]
        stateShowPosition =    [3,5,1,1]
        stateRunPosition =     [3,6,1,1]
    running = 1
    currentState = 0
    demoTimer = 0
    timerEvent = 0
    runLock = 0
    runStateKey = 0
    
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.frame = Frame
        self.grid()
        self.createWidgets()
        self.demoTimer = Timer(5.0, self.timeout)
        self.timerEvent = Event()
        self.runLock = Lock()
        self.runLock.acquire()

    def quit(self,key=0):
        if key:
            self.btnActivation(1)
            self.runStateKey = key
        else:
            self.running = 0
        self.frame.quit(self)

    def timeout(self):
        self.timerEvent.set()
        self.buttonPause["text"] = "Pause"
        self.runLock.release()
        
    def setPlatform(self,platform):
        self.textPlatform['text'] = "Chassis:\n" + platform
  
    """
    updateState is called when runScript obtains the runLock to commemnce the script
    the 'FINISHED' state is the exception
    """
    def updateState(self,state):
        self.currentState = state
        self.textState["text"] = dicStateInfo[self.currentState][STATEMSG]
        if self.currentState == FINISHED:
            self.runLock.acquire()
            self.buttonPause['state'] = DISABLED
            self.btnActivation(0)
  
    def pauseHandler(self,event):
        if not self.timerEvent.isSet():
            self.demoTimer.cancel()
            self.buttonPause["text"] = "Resume"
            self.timerEvent.set()
            self.btnActivation(0)
            txt="Paused"
        elif self.buttonPause["text"] == "Resume":
            #Resume means to release the customDeployment thread
            if not self.currentState == FINISHED:
                self.buttonPause["text"] = "Pause"
                self.btnActivation(1)
                self.runLock.release()
            txt = ''
        elif self.buttonPause["text"] == "Pause":
            self.buttonPause["text"] = "Pausing"
            if not self.runStateKey:
                self.runLock.acquire()
                self.buttonPause["text"] = "Resume"
                self.btnActivation(0)
                txt="Paused"
            else:
                txt=''
        else: # "Pausing" nothing to do but wait
            txt = ''
        #self.buttonPause.grid_forget()
        if txt:
            self.textState["text"] = txt
        
    def updateDetail(self,text="testing text widget insert\n"):
        self.textDetail.insert(END,text)
        
    def btnActivation(self,deAct):
        for stateKey in dicTKdemoInfo.keys():
            if not dicTKdemoInfo[stateKey][2]:
                continue
            if deAct:
                #demoState[1]['state'] = DISABLED
                dicTKdemoInfo[stateKey][2]['state'] = DISABLED
            else:
                #demoState[1]['state'] = NORMAL
                dicTKdemoInfo[stateKey][2]['state'] = NORMAL
        
    def btnMouseEnter(self,event):
        event.widget['fg'] = 'red'    
        
    def btnMouseLeave(self,event):
        event.widget['fg'] = 'black'    
        
    def btnScript(self,event):
        for stateKey in dicTKdemoInfo.keys():
            if event.widget == dicTKdemoInfo[stateKey][1]:
                self.showDemoScript(dicStateInfo[stateKey][STATESCRIPT])
                break
            if event.widget == dicTKdemoInfo[stateKey][2]:
                self.quit(stateKey)
                break
        else:
            tkMessageBox.showinfo("","No button found for for "+event.widget['text'] )
        event.widget['relief'] = RAISED
        
    def btnStore(self,event):
        from config import DeploymentStore
        if event.widget == self.buttonInfo:
            xmlfile = os.path.join(DeploymentStore,'SystemInfo.xml')
        else:
            xmlfile = os.path.join(DeploymentStore,'SystemLog.xml')        
        if not os.path.exists(xmlfile):
            tkMessageBox.showinfo("","System Info file does not exist: "+xmlfile)
            return
        #tkMessageBox.showinfo("","Show: "+xmlfile)
        root = Tk()
        root.title("Show: "+xmlfile)
        root.geometry("600x600")
        # height & width are rows and columns
        textScript = ScrolledText(root,height='45',width='94')
        textScript.frame.grid_propagate(0)
        textScript.grid(row=0, column=0)
        fd=open(xmlfile,'r')
        textScript.insert(END,fd.read())
        fd.close()
        event.widget['relief'] = RAISED
        
    def showDemoScript(self,script):
        if script[-3:] == '.py':
            pass
        elif sys.platform == 'linux2':
            script = script + '.sh'
        elif sys.platform == 'win32':
            script = script + '.cmd'
        if not os.path.exists(script):
            tkMessageBox.showinfo("","Script does not exist: "+script)
            return
        #tkMessageBox.showinfo("","Show: "+script)
        root = Tk()
        root.title("Show: "+script)
        root.geometry("600x600")
        # height & width are rows and columns
        textScript = ScrolledText(root,height='45',width='94')
        textScript.frame.grid_propagate(0)
        textScript.grid(row=0, column=0)
        fd=open(script,'r')
        textScript.insert(END,fd.read())
        fd.close()

    def finishedScript(self):
        if self.runStateKey:
            self.runStateKey = 0
            self.textState["text"] = 'Paused'
            self.btnActivation(0)
               
    def createWidgets(self):
        self.textPlatform = Label(self, font=("Helvetica", 12))
        self.textPlatform['text'] = "Chassis\nUnknown"
        self.textPlatform.grid(row=self.platformPosition[0], column=self.platformPosition[1], columnspan=self.platformPosition[3])
        
        self.textStates = Label(self, font=("Helvetica", 12))
        self.textStates['text'] = "Deployment Scripts"
        self.textStates.grid(row=self.statesPosition[0], column=self.statesPosition[1], columnspan=self.statesPosition[3])
        
        rowOffset = 0
        for demoState in dicTKdemoInfo.values():
            demoState[0] = Label(self, font=("Helvetica", 12))
            demoState[0]['text'] = demoState[3]
            demoState[0].grid(row=self.stateLabelPosition[0]+rowOffset, column=self.stateLabelPosition[1], columnspan=self.stateLabelPosition[3])
        
            demoState[1] = Button(self,state=NORMAL,activeforeground='red')
            demoState[1]["text"] = "Show Script"
            demoState[1].bind("<ButtonRelease>",self.btnScript)
            demoState[1].bind("<Enter>",self.btnMouseEnter)
            demoState[1].bind("<Leave>",self.btnMouseLeave)
            #demoState[1]["command"] = self.btnScript
            demoState[1].grid(row=self.stateShowPosition[0]+rowOffset, column=self.stateShowPosition[1])
        
            demoState[2] = Button(self,state=DISABLED,activeforeground='red')
            demoState[2]["text"] = "Run Script"
            demoState[2].bind("<ButtonRelease>",self.btnScript)
            demoState[2].bind("<Enter>",self.btnMouseEnter)
            demoState[2].bind("<Leave>",self.btnMouseLeave)
            #demoState[2]["command"] = self.btnScript
            demoState[2].grid(row=self.stateRunPosition[0]+rowOffset, column=self.stateRunPosition[1])
            rowOffset = rowOffset+2
        
        self.buttonInfo = Button(self,state=NORMAL,activeforeground='red')
        self.buttonInfo["text"] = "Show System Info file"
        self.buttonInfo.bind("<ButtonRelease>",self.btnStore)
        self.buttonInfo.bind("<Enter>",self.btnMouseEnter)
        self.buttonInfo.bind("<Leave>",self.btnMouseLeave)
        #self.buttonInfo["command"] = self.btnStore
        self.buttonInfo.grid(row=self.stateShowPosition[0]+rowOffset+2, column=self.stateShowPosition[1])
        
        self.buttonLog = Button(self,state=NORMAL,activeforeground='red')
        self.buttonLog["text"] = "Show System Log file"
        self.buttonLog.bind("<ButtonRelease>",self.btnStore)
        self.buttonLog.bind("<Enter>",self.btnMouseEnter)
        self.buttonLog.bind("<Leave>",self.btnMouseLeave)
        #self.buttonLog["command"] = self.btnStore
        self.buttonLog.grid(row=self.stateRunPosition[0]+rowOffset+2, column=self.stateRunPosition[1])
        
        self.textTitle = Label(self, font=("Helvetica", 36))
        self.textTitle['text'] = "PDK Deployment Demo"
        self.textTitle.grid(row=self.titlePosition[0], column=self.titlePosition[1], rowspan=self.titlePosition[2], columnspan=self.titlePosition[3])
        
        self.textState = Label(self, font=("Helvetica", 36), bd=72, fg="blue")
        self.textState['text'] = "Resuming in 5 seconds"
        self.textState.grid(row=self.statePosition[0], column=self.statePosition[1], rowspan=self.statePosition[2], columnspan=self.statePosition[3])
        
        self.buttonPause = Button(self)
        self.buttonPause["text"] = "Pause"
        self.buttonPause.bind("<ButtonRelease>",self.pauseHandler)
        #self.buttonPause["command"] = self.pauseHandler
        self.buttonPause.grid(row=self.pausePosition[0], column=self.pausePosition[1], sticky=SE)

        self.buttonQuit = Button(self)
        self.buttonQuit["text"] = "Quit"
        self.buttonQuit["fg"]   = "red"
        self.buttonQuit["command"] =  self.quit
        self.buttonQuit.grid(row=self.quitPosition[0], column=self.quitPosition[1], sticky=SW)

        self.textDetail = ScrolledText(self)
        self.textDetail.grid(row=self.detailPosition[0], column=self.detailPosition[1], rowspan=self.detailPosition[2], columnspan=self.detailPosition[3])

        #self.buttonDetail = Button(self)
        #self.buttonDetail["text"] = "Test Detail"
        #self.buttonDetail["command"] = self.updateDetail
        #self.buttonDetail.grid(row=self.detailButtonPosition[0], column=self.detailButtonPosition[1], sticky=SE)

def startDemo():
    demoApp = PDKdemo()
    demoApp.master.title("PDK Demo Deployment")
    if sys.platform == 'linux2':
        demoApp.master.geometry("800x670")
    else:
        # Default WinPE resolution in "800x600"
        demoApp.master.geometry("1000x800")
    #tkMessageBox.showinfo("","DeployPath: %s"%DeployPath)
    demoApp.demoTimer.start() # after 5 seconds, Demo resumes automatically
    return demoApp
    
if __name__=="__main__":
    demo = startDemo()
    demo.mainloop()
    

