#! /usr/bin/env python3.4
#
#########################
#      $Author: ee364f03 $
#      $Date: 2015-12-06 02:02:10 -0500 (Sun, 06 Dec 2015) $
#      $HeadURL: svn+ssh://ece364sv@ecegrid-thin1/home/ecegrid/a/ece364sv/svn/F15/students/ee364f03/Lab11/HomographyApp.py $
#      $Revision: 83647 $
#
#########################


import sys
import re
import random
from PySide.QtGui import *
from PySide.QtCore import *

from HomographyGUI import *
from enum import Enum
from Homography import *

class State(Enum):
    initial = 0
    loaded = 1
    selection = 2
    ready = 3
    transformed = 4


class EntryApplication(QMainWindow, Ui_MainWindow):

    def __init__(self, parent=None):

        super(EntryApplication, self).__init__(parent)
        self.setupUi(self)

        self.btnLoadSource.clicked.connect(self.loadSource)
        self.btnLoadTarget.clicked.connect(self.loadTarget)
        #self.viewSourceImage.
        #self.viewTargetImage.
        self.btnAcquirePoints.clicked.connect(self.acquirePoints)

        self.btnTransform.clicked.connect(self.transform)
        self.btnReset.clicked.connect(self.reset)
        self.btnSave.clicked.connect(self.save)

        #self.txtAddress.textChanged.connect(self.dataEntered)
        self.state = State.initial

        self.loadedSource = False
        self.loadedTarget = False
        self.reloadTarget = False
        self.newLoad = False

        self.viewTargetImage.mousePressEvent = self.getPos

        self.origx = 1
        self.origy = 1
        self.scale = 1
        self.offset = 1
        self.small = 'z'

        self.sourcePath = ''
        self.targetPath = ''


        self.tupleUL = (0,0)
        self.tupleUR = (0,0)
        self.tupleLL = (0,0)
        self.tupleLR = (0,0)

        self.savePath = '/home/ecegrid/a/ee364f03/Lab11/TestImages/GUI.png'



    def loadSource(self):
        self.loadedSource = self.load(self.viewSourceImage)
        self.updateState()

    def loadTarget(self):
        if self.loadedTarget == True:
            self.reloadTarget = True
        self.loadedTarget = self.load(self.viewTargetImage)
        self.updateState()


    def getPos(self, event):
        xinit = event.pos().x()
        yinit = event.pos().y()


        x = int(xinit * self.scale)
        y = int(yinit * self.scale)

        if self.small == 'x':
            x = x - self.offset
        elif self.small == 'y':
            y = y - self.offset

        x = int(x)
        y = int(y)

        self.acquirePoints(point=(x,y))
        #print('Orig: ' + str(self.origx) + ', ' + str(self.origy))
        #print('Init: ' + str(xinit) + ', ' + str(yinit))
        #print('Scale: ' + str(self.scale))
        #print('Offset: ' + str(self.offset))
        #print('Final: ' + str(x) + ', ' + str(y))
        #print()


    def load(self,view,filePath=None, newStuff=None):
        #Obtain a file name from a file dialog, and pass it on to the loading method. This is to facilitate automated
        #testing. Invoke this method when clicking on the 'load' button.

        if filePath == None:
            filePath, _ = QFileDialog.getOpenFileName(self, caption='Open image file ...', filter="PNG files (*.png)")

            if not filePath:
                return False

        self.newLoad = True
        if view == self.viewSourceImage and newStuff == None:
            self.sourcePath = filePath
        elif view == self.viewTargetImage and newStuff == None:
            self.targetPath = filePath



        scene = QtGui.QGraphicsScene()
        pic = QtGui.QPixmap(filePath)
        #QGraphicsPixmapItem.mousePressEvent()

        if view == self.viewTargetImage:
            self.origx = pic.width()
            self.origy = pic.height()

        maxSize = QtCore.QSize(pic.width(),pic.height())
        maxSize.scale(248,248,Qt.KeepAspectRatio)
        pic = pic.scaled(maxSize.width(),maxSize.height(),aspectRatioMode=Qt.IgnoreAspectRatio)

        if view == self.viewTargetImage:
            biggest = max(self.origx,self.origy)
            if biggest > 248:
                self.scale = biggest / 248
            smallest = min(self.origx,self.origy)

            if smallest == self.origx:
                self.small = 'x'
            else:
                self.small = 'y'

            self.offset = (248 - smallest / self.scale)


        scene.addItem(QtGui.QGraphicsPixmapItem(pic))
        view.setScene(scene)
        view.setRenderHint(QtGui.QPainter.Antialiasing)
        view.show()

        return True



    def acquirePoints(self,point=None):
        self.updateState()
        if self.state == State.selection and point != None:
            if self.pointUL.text() == '':
                self.pointUL.setText(str(point))
                self.tupleUL = point
            elif self.pointUR.text() == '':
                self.pointUR.setText(str(point))
                self.tupleUR = point
            elif self.pointLL.text() == '':
                self.pointLL.setText(str(point))
                self.tupleLL = point
            elif self.pointLR.text() == '':
                self.pointLR.setText(str(point))
                self.tupleLR = point

    def transform(self):
        if self.state == State.ready:
            self.state = State.transformed

        ef = self.comboEffect.currentText()
        if ef == 'Nothing':
            ef = None
        elif ef == 'Rotate 90':
            ef = Effect.rotate90
        elif ef == 'Rotate 180':
            ef = Effect.rotate180
        elif ef == 'Rotate 270':
            ef = Effect.rotate270
        elif ef == 'Flip Horizontally':
            ef = Effect.flipHorizontally
        elif ef == 'Flip Vertically':
            ef = Effect.flipVertically
        elif ef == 'Transpose':
            ef = Effect.transpose


        tr = Transformation(imread(self.sourcePath))
        tr.setupTransformation([self.tupleUL, self.tupleUR, self.tupleLL,self.tupleLR],effect=ef)
        output = imsave('/home/ecegrid/a/ee364f03/Lab11/TestImages/GUI.png',tr.transformImage(imread(self.targetPath)))


        self.load(self.viewTargetImage,filePath='/home/ecegrid/a/ee364f03/Lab11/TestImages/GUI.png',newStuff=1)
        self.newLoad = False
        self.reloadTarget = False


        self.updateState()

    def reset(self):
        if self.state == State.transformed:
            self.state = State.ready
            self.load(self.viewTargetImage,filePath=self.targetPath,newStuff=1)
        self.updateState()

    def save(self):
            filePath, _ = QFileDialog.getSaveFileName(self, caption='Save image file ...', filter="PNG files (*.png)")
            if not filePath:
                return False
            self.savePath = filePath
            if self.state == State.ready:
                imsave(self.savePath,imread(self.targetPath))
            elif self.state == State.transformed:
                imsave(self.savePath,imread('/home/ecegrid/a/ee364f03/Lab11/TestImages/GUI.png'))

    def updateState(self):
        #from initial to loaded
        if self.loadedTarget and self.loadedSource and self.state == State.initial:
            self.state = State.loaded

        #from loaded to selection
        elif self.state == State.loaded and self.btnAcquirePoints.isChecked():
            self.state = State.selection

        #from selection to ready
        elif self.state == State.selection and self.pointUL.text() != '' and self.pointUR.text() != '' and self.pointLL.text() != '' and self.pointLR.text() != '' and not self.btnAcquirePoints.isChecked():
                self.state = State.ready

        #from selection to loaded
        elif self.state == State.selection and not self.btnAcquirePoints.isChecked():
            self.state = State.loaded

        #from ready to loaded
        elif self.state == State.ready and self.reloadTarget == True:
            self.state = State.loaded

        #from ready to selection
        elif self.state == State.ready and self.btnAcquirePoints.isChecked():
            self.state = State.selection

        #from ready to transform (part of transform button)


        #from transformed to loaded
        elif self.state == State.transformed and self.newLoad == True:
            self.state = State.loaded

        #from transformed to ready (part of reset)


        self.stateLogic()
        print(self.state)

    def stateLogic(self):
        self.newLoad = False
        self.reloadTarget = False
        if self.state == State.initial:
            self.btnLoadSource.setEnabled(True)
            self.btnLoadTarget.setEnabled(True)
            self.btnAcquirePoints.setEnabled(False)
            self.pointUL.setEnabled(False)
            self.pointUR.setEnabled(False)
            self.pointLL.setEnabled(False)
            self.pointLR.setEnabled(False)
            self.comboEffect.setEnabled(False)
            self.btnTransform.setEnabled(False)
            self.btnReset.setEnabled(False)
            self.btnSave.setEnabled(False)
            self.pointUL.setText('')
            self.pointUR.setText('')
            self.pointLL.setText('')
            self.pointLR.setText('')


        elif self.state == State.loaded:
            self.btnLoadSource.setEnabled(True)
            self.btnLoadTarget.setEnabled(True)
            self.btnAcquirePoints.setEnabled(True)
            self.pointUL.setEnabled(True)
            self.pointUR.setEnabled(True)
            self.pointLL.setEnabled(True)
            self.pointLR.setEnabled(True)
            self.btnTransform.setEnabled(False)
            self.btnReset.setEnabled(False)
            self.btnSave.setEnabled(False)
            self.comboEffect.setEnabled(False)
            self.pointUL.setText('')
            self.pointUR.setText('')
            self.pointLL.setText('')
            self.pointLR.setText('')

        elif self.state == State.selection:
            self.btnLoadSource.setEnabled(False)
            self.btnLoadTarget.setEnabled(False)
            self.btnAcquirePoints.setEnabled(True)
            self.pointUL.setEnabled(True)
            self.pointUR.setEnabled(True)
            self.pointLL.setEnabled(True)
            self.pointLR.setEnabled(True)
            self.btnTransform.setEnabled(False)
            self.btnReset.setEnabled(False)
            self.btnSave.setEnabled(False)
            self.comboEffect.setEnabled(False)
            #self.pointUL.setText('')
            #self.pointUR.setText('')
            #self.pointLL.setText('')
            #self.pointLR.setText('')

        elif self.state == State.ready:
            self.btnLoadSource.setEnabled(True)
            self.btnLoadTarget.setEnabled(True)
            self.btnAcquirePoints.setEnabled(True)
            self.pointUL.setEnabled(True)
            self.pointUR.setEnabled(True)
            self.pointLL.setEnabled(True)
            self.pointLR.setEnabled(True)
            self.btnTransform.setEnabled(True)
            self.btnReset.setEnabled(True)
            self.btnSave.setEnabled(True)
            self.comboEffect.setEnabled(True)
            #self.pointUL.setText('')
            #self.pointUR.setText('')
            #self.pointLL.setText('')
            #self.pointLR.setText('')

        elif self.state == State.transformed:
            self.btnLoadSource.setEnabled(True)
            self.btnLoadTarget.setEnabled(True)
            self.btnAcquirePoints.setEnabled(False)
            self.pointUL.setEnabled(False)
            self.pointUR.setEnabled(False)
            self.pointLL.setEnabled(False)
            self.pointLR.setEnabled(False)
            self.btnTransform.setEnabled(True)
            self.btnReset.setEnabled(True)
            self.btnSave.setEnabled(True)
            self.comboEffect.setEnabled(True)
            #self.pointUL.setText('')
            #self.pointUR.setText('')
            #self.pointLL.setText('')
            #self.pointLR.setText('')


    def keyPressEvent(self, e):
        if e.key() == QtCore.Qt.Key_Escape:
            self.close()
        if e.key() == QtCore.Qt.Key_Backspace:
            if self.pointLR.text() != '':
                self.pointLR.setText('')
            elif self.pointLL.text() != '':
                self.pointLL.setText('')
            elif self.pointUR.text() != '':
                self.pointUR.setText('')
            elif self.pointUL.text() != '':
                self.pointUL.setText('')

    def targetPress(self):
        print(self.cursor())
        print('mouse')







if __name__ == "__main__":
    currentApp = QApplication(sys.argv)
    currentForm = EntryApplication()

    currentForm.show()
    currentApp.exec_()
