#! /usr/bin/python2   # for arch linux 

import logging
import os
import pickle
import shutil
import sys
from PyQt4 import QtGui, QtCore

basedir = "" if "win" in sys.platform else os.getenv("HOME")

PICKLE_PATH = os.path.join(basedir, "tech_events.pickle")
TECHS = ('brian', 'doug', 'jason', 'simeon','tom', 'dibb')

class Event(object):
    '''
    a custom data type storing event attributes
    '''
    def __init__(self, tech, tyme):
        self.tech = tech
        self.tyme = tyme

    def __cmp__(self, other):
        return cmp(self.tyme, other.tyme)

    def __repr__(self):
        return "%s called at %s"% (self.tech.ljust(12), self.tyme)

class EventData(object):
    '''
    a custom class to manage the application data 
    '''   
    def __init__(self):
        try:
            f = open(PICKLE_PATH, "r")
            self.event_list = pickle.load(f)
            f.close()
            logging.debug("loaded data from %s"% PICKLE_PATH)
            logging.debug("making a backup file %s"% (PICKLE_PATH+"~"))
            shutil.move(PICKLE_PATH, PICKLE_PATH+"~")
            
        except IOError:
            logging.debug("creating new event list")
            self.event_list = []

    def add(self, name, time):
        self.event_list.append(Event(name, time))
    
    def clear(self):
        self.event_list = []
       
    def output(self):
        '''
        print the event list out to stdout
        '''
        for event in self.event_list:
            print (event)
    
    def to_readable_list(self):
        '''
        return a list of events as strings
        '''
        retarg = []
        for event in self.event_list:
            retarg.append(str(event))
        return retarg
        
    def tail(self, n=10):
        '''
        print the last 10 events to std out
        '''
        for event in event_list[-n:]:
            print (event)
    
    def save(self):
        '''
        save the data to the pickle file
        '''
        logging.info("saving data")
        f = open(PICKLE_PATH, "w")
        pickle.dump(self.event_list, f)
        f.close()

class TechWidget(QtGui.QWidget):
    '''
    A button, and a label.
    '''
    clicked = QtCore.pyqtSignal(object, object)

    def __init__(self, name, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.name = name
        self.num = 0 
        button = QtGui.QPushButton(self.name)
        self.label = QtGui.QLabel()
        
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(button)
        layout.addWidget(self.label)

        button.clicked.connect(self.take_call)

    def update_label(self):
        message = "%d calls since app start"% self.num
        self.label.setText(message)
        
    def take_call(self):
        self.num += 1
        self.update_label()
        self.clicked.emit(self.name, QtCore.QTime.currentTime().toPyTime())

class ListDialog(QtGui.QDialog):
    '''
    a dialog to show the events
    '''
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)
        self.setWindowTitle("Events")
        
        button_box = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok)
        button_box.setCenterButtons(True)

        layout = QtGui.QVBoxLayout(self)
        
        self.list_widget = QtGui.QListWidget()
        
        layout.addWidget(self.list_widget)
        layout.addWidget(button_box)
        
        button_box.accepted.connect(self.accept)
        
    def sizeHint(self):
        return QtCore.QSize(200, 300)


class MyWindow(QtGui.QMainWindow):
    def __init__(self, parent = None):
        QtGui.QMainWindow.__init__(self, parent)
        self.setWindowTitle("Tech Call Counter")
        
        self.event_data = EventData()
        
        widget = QtGui.QWidget(self)
        layout = QtGui.QHBoxLayout(widget)

        for tech in TECHS:
            widg = TechWidget(tech, self)
            widg.clicked.connect(self.event_data.add)
            layout.addWidget(widg)
            
        self.setCentralWidget(widget)
        
        menubar = self.menuBar()
        
        action_list = QtGui.QAction("&List Events", self)
        action_clear = QtGui.QAction("&Clear Events", self)
        icon = QtGui.QIcon.fromTheme("application-exit")
        action_quit = QtGui.QAction(icon, "&Quit", self)
        
        action_list.triggered.connect(self.show_list)
        action_clear.triggered.connect(self.clear_events)
        action_quit.triggered.connect(
            QtGui.QApplication.instance().closeAllWindows)
        
        menu_file = QtGui.QMenu("&File", self)
        menu_file.addAction(action_list)
        menu_file.addAction(action_clear)
        menu_file.addAction(action_quit)
        
        self.menuBar().addMenu(menu_file)
        
    def show_list(self, event=None):
        dl = ListDialog(self)
        dl.list_widget.addItems(self.event_data.to_readable_list())
        dl.exec_() 
    
    def clear_events(self, event=None):
        if QtGui.QMessageBox.question(self, "Confirm", "Clear today's events?",
        QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
        QtGui.QMessageBox.No) == QtGui.QMessageBox.Yes:
            self.event_data.clear()    
            
    def closeEvent(self, event=None):
        if (QtGui.QMessageBox.question(self, "Quit?",
            "Quit application?",
            QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) ==
            QtGui.QMessageBox.Yes):
            self.event_data.save()
            self.event_data.output()
            QtGui.QMainWindow.closeEvent(self, event)
        else:
            event.ignore()
                    

if __name__ == "__main__":
    logging.basicConfig(level = logging.DEBUG)
    app = QtGui.QApplication([])
    mw = MyWindow()
    mw.show()
    app.exec_()
