#!/usr/bin/env python
# JV website generator
# (c) 2008, Johan Tuitman
# Licentie: GPL
#
# GUI voor menu structuur
import wx
import cPickle
import guiSubs
import dataStruct
import pict
import os

class jvweb(wx.Frame):
    def __init__(self,db):
        wx.Frame.__init__(self, None, -1, 'JV website generator',
                size=(900, 600))

        self.err = False
        if (db==False):
            dlg = wx.MessageDialog(self, "Fout tijdens het lezen van de database. \n" + \
                 "Druk op ok om met een lege database verder te gaan." \
                , "Lezen database",  wx.OK | wx.CANCEL | wx.ICON_ERROR)
            if dlg.ShowModal() == wx.ID_OK:
                db = dataStruct.WSData()
            else:
                self.err = True
                dlg.Destroy()
                self.Destroy()
                return
            dlg.Destroy()

        self.db = db
        self.LB = []
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
        self.BuildGui()
        self.DisplayGegevens()
        self.DisplayAlgemeen()
        
    def BuildGui(self):
        self.panel = wx.Panel(self, -1)

        hsizerh = wx.BoxSizer(wx.HORIZONTAL)

        # linker kant
        vsizerLB = wx.BoxSizer(wx.VERTICAL)

        self.LB.append(wx.StaticBox(self.panel, -1, "Hoofd menu" ))
        self.LBS = []
        self.LBS.append(guiSubs.extraListBox(self,self.panel,self.db.getMenus(),'NL'))

        self.LB.append(wx.StaticBox(self.panel, -1, "Sub menu" ))
        self.LBS.append(guiSubs.extraListBox(self,self.panel,[],'NL'))
        
        # plaatjes
        self.LB.append(wx.StaticBox(self.panel, -1, "Plaatjes dirs" ))
        self.LBS.append(guiSubs.extraListBox2(self,self.panel,[],'NL'))

        self.Bind(guiSubs.EVT_NEW_ITEM,self.NewItem1,self.LBS[0].GetLb())
        self.Bind(guiSubs.EVT_DEL_ITEM,self.DelItem1,self.LBS[0].GetLb())
        self.Bind(guiSubs.EVT_CHANGE_ITEM,self.OnChangeLBox1,self.LBS[0].GetLb())

        self.Bind(guiSubs.EVT_NEW_ITEM,self.NewItem2,self.LBS[1].GetLb())
        self.Bind(guiSubs.EVT_DEL_ITEM,self.DelItem2,self.LBS[1].GetLb())
        self.Bind(guiSubs.EVT_CHANGE_ITEM,self.OnChangeLBox2,self.LBS[1].GetLb())

        self.Bind(guiSubs.EVT_NEW_ITEM,self.NewPic,self.LBS[2].GetLb())
        self.Bind(guiSubs.EVT_DEL_ITEM,self.DelPic,self.LBS[2].GetLb())
        self.Bind(guiSubs.EVT_CHANGE_ITEM,self.OnChangePic,self.LBS[2].GetLb())
        self.LBK = []
        hsizerLB1=[]
        vsizerLB1=[]
        
        for i in range(2):
            vsizerLB1.append(wx.BoxSizer(wx.VERTICAL))
            hsizerLB1.append(wx.StaticBoxSizer(self.LB[i],wx.HORIZONTAL))
            for b in ['A','De','U','Do']:
                exec 'vsizerLB1[-1].Add(self.LBS[%1i].GetButton' %i +b+'(),0,wx.ALL,3)'
            lb = self.LBS[i].GetLb()
            lb.SetMinSize((200,100))
            hsizerLB1[-1].Add(lb,1,wx.EXPAND|wx.ALL,3)
            hsizerLB1[-1].Add(vsizerLB1[-1],0,wx.ALL,3)
            vsizerLB.Add(hsizerLB1[-1],1,wx.EXPAND|wx.ALL,3)

        vsizerLB1.append(wx.BoxSizer(wx.VERTICAL))
        hsizerLB1.append(wx.BoxSizer(wx.HORIZONTAL))
        hsizerLB1.append(wx.StaticBoxSizer(self.LB[2],wx.HORIZONTAL))
        vsizerLB1.append(wx.BoxSizer(wx.VERTICAL))
        for b in ['A','De']:
            exec 'vsizerLB1[-2].Add(self.LBS[2].GetButton' +b+'(),0,wx.ALL,3)'
        lb = self.LBS[2].GetLb()
        lb.SetMinSize((200,100))

        vsizerLB1[-1].Add(lb,1,wx.EXPAND|wx.ALL,3)

        hsizerLB1[-2].Add(wx.StaticText(self.panel,-1,'Titel:'),0,wx.ALL,3)
        self.LBS.append(wx.TextCtrl(self.panel))
        hsizerLB1[-2].Add(self.LBS[-1],1,wx.EXPAND|wx.ALL,3)
        vsizerLB1[-1].Add(hsizerLB1[-2],0,wx.EXPAND)

        hsizerLB1[-1].Add(vsizerLB1[-1],1,wx.EXPAND | wx.ALL,3)
        hsizerLB1[-1].Add(vsizerLB1[-2],0,wx.EXPAND)
        vsizerLB.Add(hsizerLB1[-1],1,wx.EXPAND|wx.ALL,3)


        # rechter kant
        vsizerR = wx.BoxSizer(wx.VERTICAL)

        hsizerK_t = wx.StaticBox(self.panel, -1, "Keuze" )
        hsizerK = wx.StaticBoxSizer(hsizerK_t,wx.HORIZONTAL)
        self.KeuzeB = []
        self.KeuzeB.append(wx.RadioButton(self.panel, -1,'Hoofd pagina',style=wx.RB_GROUP))
        self.KeuzeB.append(wx.RadioButton(self.panel, -1,'Hoofd menu'))
        self.KeuzeB.append(wx.RadioButton(self.panel, -1,'Sub menu'))
        for i in self.KeuzeB:
            hsizerK.Add(i,1,wx.EXPAND|wx.ALL,3)
            self.Bind(wx.EVT_RADIOBUTTON, self.ChangeSel,i)
        vsizerR.Add(hsizerK,0,wx.EXPAND|wx.ALL,3)

        self.geg = {}
        vsizerG_t = wx.StaticBox(self.panel, -1, "Pagina gegevens" )
        vsizerG = wx.StaticBoxSizer(vsizerG_t,wx.VERTICAL)
        gsizerG = wx.GridBagSizer(hgap=3,vgap=3)
        # naam
        gsizerG.Add(wx.StaticText(self.panel,-1,'Volledige naam:'),pos=(0,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        self.geg['naam']=wx.TextCtrl(self.panel)
        gsizerG.Add(self.geg['naam'],pos=(0,1),flag=wx.EXPAND)
        # url
        gsizerG.Add(wx.StaticText(self.panel,-1,'Bestand:'),pos=(1,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        self.geg['url']=wx.TextCtrl(self.panel)
        gsizerG.Add(self.geg['url'],pos=(1,1),flag=wx.EXPAND)
        picAdd = pict.getAddBitmap()
        buttonURL = wx.BitmapButton(self.panel,-1,pict.getDirBitmap())
        gsizerG.Add(buttonURL,pos=(1,2))
        self.Bind( wx.EVT_BUTTON,self.OnButtonURL,buttonURL)
        # html bewerken
        gsizerG.Add(wx.StaticText(self.panel,-1,'HTML bewerken:'),pos=(2,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        self.geg['process']=wx.CheckBox(self.panel)
        gsizerG.Add(self.geg['process'],pos=(2,1),flag=wx.ALIGN_LEFT)
        # sub bestanden
        gsizerG.Add(wx.StaticText(self.panel,-1,'Sub bestanden:'),pos=(3,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        self.geg['subProcess']=wx.CheckBox(self.panel)
        gsizerG.Add(self.geg['subProcess'],pos=(3,1),flag=wx.ALIGN_LEFT)
        # nieuw scherm
        gsizerG.Add(wx.StaticText(self.panel,-1,'Nieuw scherm:'),pos=(4,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        self.geg['newWin']=wx.CheckBox(self.panel)
        gsizerG.Add(self.geg['newWin'],pos=(4,1),flag=wx.ALIGN_LEFT)
        # extra bestanden
        gsizerG.Add(wx.StaticText(self.panel,-1,'Extra bestanden:'),pos=(5,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        self.geg['addFiles']=guiSubs.extraListBox2(self,self.panel,[],'NL')
        gsizerG.Add(self.geg['addFiles'].GetLb(),pos=(5,1),flag=wx.EXPAND)
        vsizerGG = wx.BoxSizer(wx.VERTICAL)
        vsizerGG.Add(self.geg['addFiles'].GetButtonA(),0,wx.ALL,3)
        vsizerGG.Add(self.geg['addFiles'].GetButtonDe(),0,wx.ALL,3)
        gsizerG.Add(vsizerGG,pos=(5,2))
        self.Bind(guiSubs.EVT_NEW_ITEM,self.NewBest,self.geg['addFiles'].GetLb())

        gsizerG.AddGrowableCol(1)
        gsizerG.AddGrowableRow(5)
        vsizerG.Add(gsizerG,1,wx.EXPAND|wx.ALL,3)
        vsizerR.Add(vsizerG,1,wx.EXPAND|wx.ALL,3)


        vsizerA_t = wx.StaticBox(self.panel, -1, "Algemeen" )
        vsizerA = wx.StaticBoxSizer(vsizerA_t,wx.VERTICAL)
        gsizerA = wx.GridBagSizer(hgap=3,vgap=3)
        self.buttons={}
        # werk dir
        gsizerA.Add(wx.StaticText(self.panel,-1,'Werk directory:'),pos=(0,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        self.geg['workDir']=wx.TextCtrl(self.panel)
        gsizerA.Add(self.geg['workDir'],pos=(0,1),flag=wx.EXPAND)
        picAdd = pict.getAddBitmap()
        self.buttons['workDir']= wx.BitmapButton(self.panel,-1,pict.getDirBitmap())
        gsizerA.Add(self.buttons['workDir'],pos=(0,2))
        self.Bind( wx.EVT_BUTTON,self.OnButtonDir,self.buttons['workDir'])
        # plaatjes dir
        gsizerA.Add(wx.StaticText(self.panel,-1,'Plaatjes directory:'),pos=(1,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        self.geg['picDir']=wx.TextCtrl(self.panel)
        gsizerA.Add(self.geg['picDir'],pos=(1,1),flag=wx.EXPAND)
        picAdd = pict.getAddBitmap()
        self.buttons['picDir']= wx.BitmapButton(self.panel,-1,pict.getDirBitmap())
        gsizerA.Add(self.buttons['picDir'],pos=(1,2))
        self.Bind( wx.EVT_BUTTON,self.OnButtonDir,self.buttons['picDir'])
        # ftp server
        gsizerA.Add(wx.StaticText(self.panel,-1,'FTP server:'),pos=(2,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        self.geg['ftpSite']=wx.TextCtrl(self.panel)
        gsizerA.Add(self.geg['ftpSite'],pos=(2,1),flag=wx.EXPAND)
        # ftp url
        gsizerA.Add(wx.StaticText(self.panel,-1,'FTP locatie:'),pos=(3,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        self.geg['ftpDirectory']=wx.TextCtrl(self.panel)
        gsizerA.Add(self.geg['ftpDirectory'],pos=(3,1),flag=wx.EXPAND)
        # ftp user
        gsizerA.Add(wx.StaticText(self.panel,-1,'FTP gebruiker:'),pos=(4,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        self.geg['ftpUser']=wx.TextCtrl(self.panel)
        gsizerA.Add(self.geg['ftpUser'],pos=(4,1),flag=wx.EXPAND)
        # ftp password
        gsizerA.Add(wx.StaticText(self.panel,-1,'FTP paswoord:'),pos=(5,0),flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        self.geg['ftpPasswd']=wx.TextCtrl(self.panel,style=wx.TE_PASSWORD)
        gsizerA.Add(self.geg['ftpPasswd'],pos=(5,1),flag=wx.EXPAND)
        gsizerA.AddGrowableCol(1)
        vsizerA.Add(gsizerA,0,wx.EXPAND|wx.ALL,3)
        vsizerR.Add(vsizerA,0,wx.EXPAND|wx.ALL,3)

        # uitvoer
        uitvoer_t = wx.StaticBox(self.panel, -1, "Uitvoeren" )
        uitvoer= wx.StaticBoxSizer(uitvoer_t,wx.HORIZONTAL)
        knoppen = []
        knoppen.append(wx.Button(self.panel,-1, "Genereren"))
        knoppen.append(wx.Button(self.panel,-1, "Re-genereren"))
        knoppen.append(wx.Button(self.panel,-1, "Annuleren"))
        for kp in knoppen:
            uitvoer.Add(kp,1,wx.ALL,3)
        self.Bind(wx.EVT_BUTTON, self.OnGenereren,knoppen[0])
        self.Bind(wx.EVT_BUTTON, self.OnReGenereren,knoppen[1])
        self.Bind(wx.EVT_BUTTON, self.OnAnnuleren,knoppen[2])
        vsizerR.Add(uitvoer,0,wx.EXPAND|wx.ALL,3)

        hsizerh.Add(vsizerLB,4,wx.EXPAND|wx.ALL,3)
        hsizerh.Add(vsizerR ,5,wx.EXPAND|wx.ALL,3)
        self.panel.SetSizer(hsizerh)

    def OnAnnuleren(self,event):
        self.err = True
        self.Destroy()

    def OnGenereren(self,event,rg=False):
        self.StoreGegevens()
        self.StoreAlgemeen()
        self.saveDb()
        if not rg:
            os.system('python genjvweb.py')
        else:
            os.system('python genjvweb.py -r')

    def OnReGenereren(self,event):
        self.OnGenereren(None,True)

    def NewPic(self,event):
        startDir, refDir = self.GetCurrentPath()
        dlg = wx.DirDialog(self, "Kies een directory:", \
                          defaultPath=startDir, \
                          style=wx.DD_DEFAULT_STYLE)

        if dlg.ShowModal() == wx.ID_OK:
            pat = dlg.GetPath()
            base = guiSubs.relPath(startDir,os.path.dirname(pat))
            bn  = os.path.join(base,os.path.basename(pat))
            pagina, level = self.GetPage()
            if pagina == None:
                return
            pagina.addPic(bn)
            self.LBS[2].AddItem(bn)

        dlg.Destroy()

    def DelPic(self,event):
        bn = event.GetItem()
        pagina, level = self.GetPage()
        if pagina == None:
            return
        pagina.delPic(bn)
        self.OnChangePic(None)

    def OnChangePic(self,event):
        bn = self.LBS[2].checkSel()
        pagina, level = self.GetPage()
        if pagina == None or bn == None:
            return
        bnn = self.LBS[2].GetLB()[bn]
        if self.LBS[2].getAssingend():
            slbi = self.LBS[2].getAssingend()
            self.pagina.setPicName(slbi,self.LBS[3].GetValue())

        self.LBS[3].SetValue(pagina.getPics()[bnn])
        self.LBS[2].setAssinged(bnn)

    def NewBest(self,event):
        startDir, refDir = self.GetCurrentPath()
        dlg = wx.FileDialog(
            self, message="Kies een bestand",
            defaultDir=startDir,
            defaultFile="",
            style=wx.OPEN
            )

        if dlg.ShowModal() == wx.ID_OK:
            pat = dlg.GetPath()
            base = guiSubs.relPath(startDir,os.path.dirname(pat))
            self.geg['addFiles'].AddItem(os.path.join(base,os.path.basename(pat)))

        dlg.Destroy()

    def OnButtonDir(self,event):
        startDir = refDir = os.getcwd()
        dlg = wx.DirDialog(self, "Kies een directory:", \
                          style=wx.DD_DEFAULT_STYLE)

        if dlg.ShowModal() == wx.ID_OK:
            pat = dlg.GetPath()
            base = guiSubs.relPath(refDir,pat)
            if event.GetId() == self.buttons['workDir'].GetId():
                self.geg['workDir'].SetValue(base)
            elif event.GetId() == self.buttons['picDir'].GetId():
                self.geg['picDir'].SetValue(base)

        dlg.Destroy()

    def OnButtonURL(self,event):
        startDir, refDir = self.GetCurrentPath()

        wildcard = 'html bestand (*.html;*.htm) |*.html;*.htm'
        dlg = wx.FileDialog(
            self, message="Kies een bestand",
            defaultDir=startDir,
            defaultFile="",
            wildcard=wildcard,
            style=wx.OPEN
            )

        if dlg.ShowModal() == wx.ID_OK:
            pat = dlg.GetPath()
            base = guiSubs.relPath(refDir,os.path.dirname(pat))
            self.geg['url'].SetValue(os.path.join(base,os.path.basename(pat)))

        dlg.Destroy()

    def GetCurrentPath(self):
        # ensure actual data is read
        self.StoreGegevens()
        startDir=os.getcwd()
        refDir = os.getcwd()
        
        if self.db.getIndexPage().getUrl() != "":
            startDir = os.path.join(startDir,os.path.dirname(self.db.getIndexPage().getUrl()))
            if self.paginaLevel > 0:
                refDir = str(startDir)
                hmenu = self.LBS[0].checkSel()
                if hmenu == None:
                    return

                if self.db.getPage(hmenu).getUrl() != "":
                    startDir = os.path.join(startDir, \
                            os.path.dirname(self.db.getPage(hmenu).getUrl()))

                elif self.paginaLevel > 1:
                    dlg = wx.MessageDialog(self, "Vul eerst de bestandnaam van het hoofdmenu in.", \
                        "Locatie fout", wx.OK | wx.ICON_ERROR)
                    dlg.ShowModal()
                    dlg.Destroy()
                    return

                if self.paginaLevel == 2:
                    refDir = str(startDir)
                    if self.pagina.getUrl() != "":
                        startDir = os.path.join(startDir, \
                                os.path.dirname(self.pagina.getUrl()))

        elif self.paginaLevel > 0:
            dlg = wx.MessageDialog(self, "Vul eerst de bestandnaam van de hoofdpagina in.", \
                "Locatie fout", wx.OK | wx.ICON_ERROR)
            dlg.ShowModal()
            dlg.Destroy()
            return

        startDir = os.path.normpath(startDir)
        refDir = os.path.normpath(refDir)
        return startDir,refDir

    def ChangeSel(self,event):
        """laat pagina gegeven van nieuwe selectie zien en bewaard oude gevens"""
        self.StoreGegevens()
        self.DisplayGegevens()

    def GetPage(self):
        """geeft de geselecteerde pagina"""
        # hoofd pagina
        if self.KeuzeB[0].GetValue():
            return self.db.getIndexPage(), 0

        # hoofd menu item
        hmenu = self.LBS[0].checkSel()
        if hmenu == None:
            return None, None
        if self.KeuzeB[1].GetValue():
            return self.db.getPage(hmenu), 1
        # submenu
        else:
            smenu = self.LBS[1].checkSel()
            if smenu == None:
                return None, None
            return self.db.getSubPage(hmenu,smenu), 2

    def DisplayGegevens(self):
        pagina, level = self.GetPage()
        if pagina == None:
            return
        self.pagina = pagina
        self.paginaLevel = level
        self.geg['naam'].SetValue(self.pagina.getFullName())
        self.geg['url'].SetValue(self.pagina.getUrl())
        self.geg['process'].SetValue(self.pagina.getProcess())
        self.geg['subProcess'].SetValue(self.pagina.getSubProcess())
        self.geg['newWin'].SetValue(self.pagina.getNewWin())
        self.geg['addFiles'].SetLB(self.pagina.getInclProc())
        self.LBS[2].SetLB(self.pagina.getPics().keys())
        self.LBS[3].SetValue('')
        self.LBS[2].setAssinged(False)

    def StoreGegevens(self):
        self.pagina.setFullName(self.geg['naam'].GetValue())
        self.pagina.setUrl(self.geg['url'].GetValue())
        self.pagina.setProcess(self.geg['process'].GetValue())
        self.pagina.setSubProcess(self.geg['subProcess'].GetValue())
        self.pagina.setNewWin(self.geg['newWin'].GetValue())
        self.pagina.setInclProc(self.geg['addFiles'].GetLB())
        slb = self.LBS[2].GetLb().GetSelections()
        if len(slb) > 0:
            slbi = self.LBS[2].GetLB()[slb[0]]
            self.pagina.setPicName(slbi,self.LBS[3].GetValue())
            self.LBS[2].setAssinged(slbi)

    def DisplayAlgemeen(self):
        self.geg['workDir'].SetValue(self.db.getWorkDir())
        self.geg['picDir'].SetValue(self.db.getPicDir())
        self.geg['ftpSite'].SetValue(self.db.getFTP().getSite())
        self.geg['ftpDirectory'].SetValue(self.db.getFTP().getDirectory())
        self.geg['ftpUser'].SetValue(self.db.getFTP().getUser())
        self.geg['ftpPasswd'].SetValue(self.db.getFTP().getPasswd())

    def StoreAlgemeen(self):
        self.db.setWorkDir(self.geg['workDir'].GetValue())
        self.db.setPicDir(self.geg['picDir'].GetValue())
        self.db.getFTP().setSite(self.geg['ftpSite'].GetValue())
        self.db.getFTP().setDirectory(self.geg['ftpDirectory'].GetValue())
        self.db.getFTP().setUser(self.geg['ftpUser'].GetValue())
        self.db.getFTP().setPasswd(self.geg['ftpPasswd'].GetValue())

    def NewItem1(self,event):
        self.db.addMenu(event.GetItem())
        self.OnChangeLBox1(event)

    def DelItem1(self,event):
        self.db.delMenu(event.GetItem())
        self.ChangeSel(None)

    def OnChangeLBox1(self,event):
        self.LBS[1].SetLB(self.db.getSubMenus(event.GetItem()))
        self.KeuzeB[1].SetValue(True)
        self.ChangeSel(None)

    def NewItem2(self,event):
        selItem = self.LBS[0].checkSel()
        if selItem != None:
            self.db.addSubMenu(selItem,event.GetItem())
            self.ChangeSel(None)

    def DelItem2(self,event):
        selItem = self.LBS[0].checkSel()
        self.db.delSubMenu(selItem,event.GetItem())
        self.ChangeSel(None)

    def OnChangeLBox2(self,event):
        self.KeuzeB[2].SetValue(True)
        self.ChangeSel(None)

    def OnCloseWindow(self,event):
        self.StoreGegevens()
        self.StoreAlgemeen()
        self.saveDb()
        self.Destroy()

    def saveDb(self):
        if self.err:
            return
        try:
            f = open('jvwebsite.db','w')
            cPickle.dump(self.db,f)
            f.close()
        except:
            dlg = wx.MessageDialog(self, "Error while writing database." \
                , "Writing database",  wx.OK | wx.ICON_ERROR)
            dlg.ShowModal()
            dlg.Destroy()
            self.Destroy()
            return

def readDb():
    try:
        f = open('jvwebsite.db')
        db = cPickle.load(f)
        f.close()
        return db
    except:
        return False


if __name__ == '__main__':
    app = wx.PySimpleApp()
    db = readDb()
    frame = jvweb(db)
    frame.Show()
    app.MainLoop()