#!/usr/bin/env python
#-*- coding: UTF-8 -*-
 
import os
import os.path
import wx
import stomasqlite
from   stomamisc import *

class DbManDialog(wx.Dialog):
    
    ID_RESET = wx.NewId()
    
    def __init__(self, parent, updateDbwin, writeToLogwin, connect2Database, config, jobtimer):        
        """  add, edit or remove backup jobs """
        wx.Dialog.__init__(self, parent, -1, TITLE + ' - Manage database',                           
                           style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)
        self.Bind(wx.EVT_CLOSE, self.onButtonClose)
        self.Bind(wx.EVT_RIGHT_DOWN, self.onContext)
        self.config = config
        self.jobtimer = jobtimer
        self.timerstate = jobtimer.IsRunning()
        jobtimer.Stop()        
        self.parent = parent
        self.updateDbwin = updateDbwin
        self.writeToLogwin = writeToLogwin
        self.connect2Database = connect2Database
        sizer = wx.BoxSizer(wx.VERTICAL)
        gbsz = wx.GridBagSizer(BORDER, BORDER)      
        
        sb = wx.StaticBox(self, -1, ' Known databases ')
        col1 = wx.StaticBoxSizer(sb, wx.HORIZONTAL)
        self.dblist = wx.ListBox(self, -1, size = wx.Size(150, -1),
                                 style = wx.LB_SINGLE | wx.LB_HSCROLL)
        col1.Add(self.dblist, 1, wx.GROW | wx.ALL, GAP)
        self.dblist.Bind(wx.EVT_RIGHT_DOWN, self.onContext)
        self.Bind(wx.EVT_LISTBOX, self.onClickDb)
        self.Bind(wx.EVT_LISTBOX_DCLICK, self.onDoubleclick)
        self.Bind(wx.EVT_CHECKLISTBOX, self.onChecked)
        gbsz.Add(col1, wx.GBPosition(0, 0), wx.GBSpan(1, 1), wx.GROW)

        sb = wx.StaticBox(self, -1, ' Database info ')
        col2 = wx.StaticBoxSizer(sb, wx.HORIZONTAL)
        self.di = wx.ListCtrl(self, -1, style = wx.LC_REPORT | wx.LC_NO_HEADER | \
                              wx.LC_SINGLE_SEL | wx.LC_HRULES | wx.BORDER_SUNKEN)
        self.di.Bind(wx.EVT_RIGHT_DOWN, self.onContext)
        self.di.InsertColumn(0, '')
        self.di.InsertColumn(1, '')
        self.di.InsertColumn(2, '')
        col2.Add(self.di, 1, wx.GROW | wx.ALL, GAP)
        gbsz.Add(col2, wx.GBPosition(0, 1), wx.GBSpan(1, 2), wx.GROW)
        
        opentxt = wx.StaticText(self, -1, ' double click database to connect / make current db')
        font = wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
        opentxt.SetFont(font)       
        gbsz.Add(opentxt, wx.GBPosition(1, 0), wx.GBSpan(1, 3), wx.GROW)        
                
        butadd = wx.Button(self, wx.ID_NEW)
        butopen = wx.Button(self, wx.ID_ADD)
        butreset = wx.Button(self, self.ID_RESET, '&Reset')
        butrem = wx.Button(self, wx.ID_DELETE)
        butclose = wx.Button(self, wx.ID_CLOSE)
        self.Bind(wx.EVT_BUTTON, self.onButtonClose, id = wx.ID_CLOSE)
        self.Bind(wx.EVT_BUTTON, self.onButtonNew, id = wx.ID_NEW)
        self.Bind(wx.EVT_BUTTON, self.onButtonAdd, id = wx.ID_ADD)
        self.Bind(wx.EVT_BUTTON, self.onButtonRem, id = wx.ID_DELETE)
        self.Bind(wx.EVT_BUTTON, self.onButtonReset, id = self.ID_RESET)
        row2 = wx.BoxSizer(wx.HORIZONTAL)
        row2.Add(butadd, 1, wx.GROW | wx.RIGHT, GAP)
        row2.Add(butopen, 1, wx.GROW | wx.LEFT | wx.RIGHT, GAP)
        row2.Add(butreset, 1, wx.GROW | wx.LEFT | wx.RIGHT, GAP)
        row2.Add(butrem, 1, wx.GROW | wx.LEFT | wx.RIGHT, GAP)
        row2.Add(butclose, 1, wx.GROW | wx.LEFT, GAP)
        gbsz.Add(row2, wx.GBPosition(2, 0), wx.GBSpan(1, 3), wx.GROW)

        self.updateList()
        try:
            index = int(self.config['Database']['index'])
            self.dblist.Select(index)
            self.onClickDb(None, self.config['Database']['dbhistory'][index])   
        except:
            print 'hier'
            pass

        gbsz.AddGrowableCol(0)
        gbsz.AddGrowableCol(1)
        gbsz.AddGrowableRow(0)

        sizer.Add(gbsz, 1, wx.GROW | wx.ALL, BORDER)
        self.SetSizer(sizer)
        self.SetMinSize(wx.Size(640, 400))
        self.Fit()
        self.Centre()
        self.initContextMenu()
    #-------------------------------------------------------------------------------------------

    def initContextMenu(self):
        self.popupID0 = wx.NewId()  
        self.popupID1 = wx.NewId()          
        self.popupID2 = wx.NewId()
        self.popupID3 = wx.NewId()
        self.popupID4 = wx.NewId()
        
        self.Bind(wx.EVT_MENU, self.onButtonNew, id = self.popupID0)
        self.Bind(wx.EVT_MENU, self.onButtonAdd, id = self.popupID1)
        self.Bind(wx.EVT_MENU, self.onButtonReset, id = self.popupID2)
        self.Bind(wx.EVT_MENU, self.onButtonRem, id = self.popupID3)
        self.Bind(wx.EVT_MENU, self.onButtonClose, id = self.popupID4)
    #-------------------------------------------------------------------------------------------

    def onContext(self, event):
        """ context menu handler """
        menu = wx.Menu()
        menu.Append(self.popupID0, 'New database')
        menu.Append(self.popupID1, 'Add database')
        menu.Append(self.popupID2, 'Reset database(s)')
        menu.Append(self.popupID3, 'Delete database(s)')
        menu.AppendSeparator()
        menu.Append(self.popupID4, 'Close dialog')
        self.PopupMenu(menu)
        menu.Destroy()
    #-------------------------------------------------------------------------------------------      

    def onChecked(self, event):  
        index = event.GetSelection()
        dbpathname = self.dblist.GetString(index)
        self.onClickDb(dbpathname = dbpathname)
    #-------------------------------------------------------------------------------------------        

    def onDoubleclick(self, event = None, dbindex = None):  
        if event == None:
            index = dbindex
        else:
            index = event.GetSelection()
        dbpathname = self.dblist.GetString(index)
        self.config['Database']['index'] = index
        self.onClickDb(dbpathname = dbpathname)
        self.connect2Database()
    #-------------------------------------------------------------------------------------------        

    def onClickDb(self, event = None, dbpathname = ''):    
        self.di.DeleteAllItems()
        
        if len(self.config['Database']['dbhistory']) == 0: return
        if event != None:
            dbpathname = event.GetString()
        if (len(dbpathname) == 0):
            dbpathname = self.config['Database']['dbhistory'][int(self.config['Database']['index'])]
                
        self.di.InsertStringItem(0, 'Db path:')
        self.di.InsertStringItem(1, 'Db size:')
        self.di.InsertStringItem(2, '')        
        self.di.InsertStringItem(3, 'Dir count:')
        self.di.InsertStringItem(4, 'File count:')
        self.di.InsertStringItem(5, '')         
        self.di.InsertStringItem(6, 'Scan runs:')
        self.di.InsertStringItem(7, 'Scan list:')
        self.di.SetColumnWidth(0, wx.LIST_AUTOSIZE)
        
        if os.path.exists(dbpathname):
            dbinfo = stomasqlite.StoreManDb(dbpathname)
            dirs = dbinfo.getDirCount()
            files = dbinfo.getRecordCount()
            head, tail = os.path.split(dbpathname)
            filesize = os.path.getsize(dbpathname)
            scandates = dbinfo.getScanDates()

            self.di.SetStringItem(0, 1, dbpathname)
            self.di.SetStringItem(1, 1, format3P(filesize) + ' bytes')
            self.di.SetStringItem(3, 1, format3P(dirs))
            self.di.SetStringItem(4, 1, format3P(files))
            self.di.SetStringItem(6, 1, format3P(len(scandates)))
            
            line = 7
            for row, item in enumerate(scandates):
                self.di.SetStringItem(line, 1, item[1])
                self.di.SetStringItem(line, 2, item[0])
                line += 1
                self.di.InsertStringItem(line, '')
        else:
            self.di.SetStringItem(0, 1, 'database does not exist')
        self.di.SetColumnWidth(1, wx.LIST_AUTOSIZE)
        self.di.SetColumnWidth(2, wx.LIST_AUTOSIZE)
    #-------------------------------------------------------------------------------------------

    def onButtonClose(self, event):
        if self.timerstate:
            self.jobtimer.Start(JOB_TIME_SLICE)        
        self.Destroy()
    #-------------------------------------------------------------------------------------------

    def onButtonNew(self, event):
        """  """
        wildcard = 'SQLite file (*.db3)|*.db3|' \
                   'All files (*.*)|*.*'

        head, tail = os.path.split(self.config['Database']['dbhistory'][int(self.config['Database']['index'])])        
        dlg = wx.FileDialog(self, TITLE + ' - create new database', head, 'default.db3',
                            wildcard, wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
        if dlg.ShowModal() == wx.ID_OK:
            path = os.path.normpath(dlg.GetPath())
            try:
                f = file(path, 'wb')    # create db file - check path for writing
                f.close()
                stomasqlite.StoreManDb(path)
            except:
                dlg = wx.MessageDialog(self, "Unable to create database. Check device or rights!",
                                       TITLE + ' - Create / add database', wx.OK | wx.ICON_ERROR)
                dlg.ShowModal()
                return
            self.writeToLogwin("Create DB - new db '%s' successfully created" % (path))
            activedb = self.config['Database']['dbhistory'][int(self.config['Database']['index'])]
            self.config['Database']['dbhistory'].append(path)
            self.config['Database']['dbhistory'].sort()
            self.config['Database']['index'] = self.config['Database']['dbhistory'].index(activedb)
            self.updateList()
        dlg.Destroy()
        self.onClickDb(None, path)
        self.dblist.Select(self.config['Database']['dbhistory'].index(path))
    #-------------------------------------------------------------------------------------------

    def onButtonAdd(self, event):
        """  """
        wildcard = 'SQLite file (*.db3)|*.db3|' \
                   'All files (*.*)|*.*'

        head, tail = os.path.split(self.config['Database']['dbhistory'][int(self.config['Database']['index'])])        
        dlg = wx.FileDialog(self, TITLE + ' - create new database', head, 'default.db3',
                            wildcard, wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
        if dlg.ShowModal() == wx.ID_OK:
            path = os.path.normpath(dlg.GetPath())
            if path in self.config['Database']['dbhistory']:
                dlg = wx.MessageDialog(self, "The selected database file\n'%s'\nis already in the Existing databases list!" % (path), TITLE + ' - Add database', wx.OK | wx.ICON_INFORMATION)
                dlg.ShowModal()
                return                
            try:
                db = stomasqlite.StoreManDb(path)
                if not db.checkDatabase()[0]: raise
            except:
                dlg = wx.MessageDialog(self, "The selected file\n'%s'\nis is not a valid StoreMan database!" % (path), TITLE + ' - Add database', wx.OK | wx.ICON_ERROR)
                dlg.ShowModal()
                return
            
            self.writeToLogwin("Add DB - db '%s' successfully added" % (path))
            activedb = self.config['Database']['dbhistory'][int(self.config['Database']['index'])]
            self.config['Database']['dbhistory'].append(path)
            self.config['Database']['dbhistory'].sort()
            self.config['Database']['index'] = self.config['Database']['dbhistory'].index(activedb)
            self.updateList()
        dlg.Destroy()
        self.onClickDb(None, path)
        self.dblist.Select(self.config['Database']['dbhistory'].index(path))
    #-------------------------------------------------------------------------------------------

    def onButtonRem(self, event):    
        activedb = self.config['Database']['dbhistory'][int(self.config['Database']['index'])]

        dbids = self.dblist.GetSelections()    
        removed = False
        if len(dbids):
            selecteddb = self.config['Database']['dbhistory'][dbids[0]]
            if activedb != selecteddb:
                dlg = wx.MessageDialog(self, "Ready to delete selected database item\n'%s' \nErase database file too?" % (selecteddb),
                                       TITLE + ' - Delete database', wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
                if dlg.ShowModal() == wx.ID_YES:                    
                    try:
                        os.remove(selecteddb) 
                    except:
                        dlg = wx.MessageDialog(self, "Unable to delete database file. Check device \nor rights!",
                                               TITLE + ' - Delete database', wx.OK | wx.ICON_ERROR)
                        dlg.ShowModal()
                del self.config['Database']['dbhistory'][dbids[0]]
                removed = True 
            else:
                dlg = wx.MessageDialog(self, "You are not allowed to delete the currently \nactive database!",
                                       TITLE + ' - Delete database', wx.OK | wx.ICON_WARNING)
                dlg.ShowModal()                                           
        
        if removed:
            self.writeToLogwin("Delete DB - database %s deleted" % (selecteddb))
        else:
            self.writeToLogwin("Delete DB - no database deleted")
        self.config['Database']['dbhistory'].sort()
        self.config['Database']['index'] = self.config['Database']['dbhistory'].index(activedb)        
        self.updateList()
        self.onClickDb()
        try:                        # maybe no more items left
            self.dblist.Select(0)
        except:
            pass            
    #-------------------------------------------------------------------------------------------

    def onButtonReset(self, event):
        dbids = self.dblist.GetSelections()
        dbreset = False
        if len(dbids):
            index = dbids[0]
            dlg = wx.MessageDialog(self, "If you reset a database you will loose all of its data.\nIs this what you realy want to do?",
                                   TITLE + ' - Reset database', wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
            if dlg.ShowModal() == wx.ID_YES:    
                activedb = self.config['Database']['dbhistory'][int(self.config['Database']['index'])]
        
                selecteddb = self.config['Database']['dbhistory'][index]
                try:
                    os.remove(selecteddb)
                    stomasqlite.StoreManDb(selecteddb)
                    dbreset = True
                    self.onDoubleclick(dbindex = index)     # update infos in views
                except:
                    dlg = wx.MessageDialog(self, "Unable to reset database. Check device \nor rights!",
                                           TITLE + ' - Reset database', wx.OK | wx.ICON_ERROR)
                    dlg.ShowModal()                    
    
        if dbreset:
            self.writeToLogwin("Reset DB - database '%s' reset" % (selecteddb))
        else:
            self.writeToLogwin("Reset DB - no database reset")
    #-------------------------------------------------------------------------------------------

    def updateList(self):
        self.dblist.Set(self.config['Database']['dbhistory'])
        self.updateDbwin()     
# - class JobsDialog(wx.Dialog):----------------------------------------------------------------

