#!/usr/bin/env python3

import sys,  threading

from PyQt5.QtCore import pyqtSlot,  pyqtSignal,  Qt
from PyQt5.QtWidgets import QApplication,  QMainWindow, QFileDialog
from PyQt5.QtGui import QFont
from binascii import hexlify

from Ui_UiForm import Ui_MainWindow as Ui
from WaitingSpinnerWidget import QtWaitingSpinner as Placeholder

from double_hash_512 import double_hash

class appWindow(QMainWindow,  Ui):
    recover = pyqtSignal()
    
    def __init__(self, parent=None):
        super(appWindow, self).__init__(parent)
        self.setupUi(self)
        
        self.chosenFileName = None
        self.buffer = None
        self.chosenFileSize = 0
        self.pushButton.clicked.connect(self.ChooseFile)
        self.setFixedSize(1100, 280)

        self.setStyleSheet("""
            QMainWindow {
                border: 2px solid black;
                border-top-left-radius: 5px;
                border-top-right-radius: 25px;
                border-bottom-left-radius: 25px;
                border-bottom-right-radius: 5px;
                }
            """)

        self.spinner = Placeholder(True,  True,  parent = self)
        
        QApplication.clipboard().dataChanged.connect(self.DisplayClipboard)

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape:
            self.close()
        super(appWindow,  self).keyPressEvent(e)    # Re-throw!


    @pyqtSlot()
    def ChooseFile(self):
        (self.chosenFileName,  _) = QFileDialog.getOpenFileName(self,  "Open File")
        if (self.chosenFileName == ""):
            return

        self.spinner.move(self.pos() - self.spinner.rect().center())
        self.spinner.start()

        prior_clip = QApplication.clipboard().text()
        if (len(prior_clip) <= 128 and prior_clip.count('\n') < 1 and prior_clip.count('\r') < 1):
            self.label_4.setFont(QFont("Courier",  8))
            self.label_4.setText("Clipboard Contents: " + prior_clip)

        t = threading.Thread(target=self.Crunch)
        t.start()
        return

    def Crunch(self):
        
        self.recover.connect(self.ReEnable)
        
        try:
            file=open(self.chosenFileName,"rb")
            self.buffer = bytearray(file.read())
            file.close()
        except IOError:
            self.label.setText("Could not open file " +  self.chosenFileName +  " for reading.")
            self.label_2.setText("Binary File Size")
            self.label_3.setText("Double Hash")

#            self.spinner.stop()
            self.recover.emit()
            return

        if (self.buffer is None):
            self.label.setText("Generic Error.")

#            self.spinner.stop()
            self.recover.emit()
            return
            
        self.label.setText("File Name: " + self.chosenFileName)
        self.label_2.setText("Binary File Size: " +  str(len(self.buffer)))
        
        hash_512 = double_hash(self.buffer)
        self.label_3.setFont(QFont("Courier",  8))
        self.label_3.setText("Double Hash:        " + str(hexlify(hash_512),  "ascii"))
        self.buffer = None

#        self.spinner.stop()
        self.recover.emit()

    @pyqtSlot()
    def DisplayClipboard(self):
        prior_clip = QApplication.clipboard().text()
        if (len(prior_clip) <= 128 and prior_clip.count('\n') < 1 and prior_clip.count('\r') < 1):
            self.label_4.setFont(QFont("Courier",  8))
            self.label_4.setText("Clipboard Contents: " + prior_clip)

    @pyqtSlot()
    def ReEnable(self):
        self.spinner.stop()

def main():
    app = QApplication(sys.argv)
    window = appWindow()
    window.setWindowFlags(Qt.FramelessWindowHint)
    """
        To-Do:
        
        In a future version, window.setMask() will be called.
        
        This will cause the app window to have a non-rectangular shape on the screen.
        However, this will also require that a 1-bit .GIF File be included as a
        resource.
        
        Python files that are compiled resources will never be put on
        show-case under the "/text" folder of the Web-site.
        
        Therefore, that future version will only be available in the
        "/binaries" folder, in the files
        
        DoubleHashGUI_s.tar.gz and DoubleHashGUI_s.zip
        
    """
    window.show()
    app.exec()

if __name__ == "__main__":
    main()
