#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
# generated by wxGlade 0.6.3 on Sat Nov 28 09:05:50 2009

import wx
import wx.richtext as rt
import wx.html as ht

# begin wxGlade: extracode
import gettext
import _winreg
import sys
import os
import os.path
import ctypes
import subprocess
from win32com.shell import shell
import win32api, win32security
import win32con
import win32event
import pywintypes
import webbrowser
import ConfigParser
# end wxGlade

_ = wx.GetTranslation

ID_MENU_EXIT = wx.NewId()
ID_MENU_ENGLISH = wx.NewId()
ID_MENU_GERMAN = wx.NewId()
ID_MENU_FRENCH = wx.NewId()

class MyFrame(wx.Frame):
    languages = [
        (wx.LANGUAGE_ENGLISH_US,'en',u'English',ID_MENU_ENGLISH),
        (wx.LANGUAGE_GERMAN,'de',u'Deutsch',ID_MENU_GERMAN),
        (wx.LANGUAGE_FRENCH,'fr',u'Français',ID_MENU_FRENCH),
    ]

    def __init__(self, *args, **kwds):
        self.config = kwds.get('cfg')
        del kwds['cfg']
        self.year = self.__cfg('General','year',2013)
        try:
            #self.elevate = ctypes.windll.shell32.IsUserAnAdmin() and self.windows_version>=6 and not self.is_elevated
            self.elevate = self.windows_version>=6 and not self.is_elevated
        except IOError:
            self.elevate = False
        self.debug = False
        maindir = self.GetMainDir()
        maindir=os.path.abspath(maindir)
        self.icon_dir = os.path.join(maindir,"icons")
        if 'dvd' in kwds:
            self.dvd = kwds['dvd']
            self.dvd=os.path.abspath(self.dvd)
            del kwds['dvd']
        else:
            self.dvd = os.path.normpath(os.path.join(maindir,self.__cfg('General','dvd','..')))
        
        for attr, section, default in (
            ('protext_dir','proTeXt','protext'),
            ('tl_dir','TeXLive','texlive'),
            ('ctan_dir','CTAN','ctan')
        ):
            setattr(self,attr,os.path.normpath(os.path.join(self.dvd,self.__cfg(section,'dir',default))))
            if not os.path.isdir(getattr(self,attr)): setattr(self,attr,None)
        
        wx.Locale.AddCatalogLookupPathPrefix(os.path.join(maindir,'locale'))
        self.language = wx.LANGUAGE_DEFAULT
        self.locale = None

        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        
        self.menubar = wx.MenuBar()
        self.file_menu = wx.Menu()
        self.file_menu.Append(ID_MENU_EXIT,'Exit')
        self.menubar.Append(self.file_menu,'File')
        self.language_menu = wx.Menu()
        self.language_menu = wx.Menu()
        for items in self.languages:
            self.language_menu.Append(items[3],items[2],kind=wx.ITEM_RADIO)
            wx.EVT_MENU(self, items[3], self.OnLanguageSelection)
        self.menubar.Append(self.language_menu,'Language')
        self.SetMenuBar(self.menubar)
        
        self.panel_1 = wx.Panel(self, -1)
        self.sizer_protext_staticbox = wx.StaticBox(self.panel_1, -1, "proTeXt")
        self.sizer_texlive_staticbox = wx.StaticBox(self.panel_1, -1, "TeX Live %s"%self.year)
        self.sizer_ctan_staticbox = wx.StaticBox(self.panel_1, -1, "CTAN")
        self.sizer_dvd_staticbox = wx.StaticBox(self.panel_1, -1, "TeX Collection DVD")
        self.label_title = wx.StaticText(self.panel_1, -1, "TeX Collection %s"%self.year)
        self.bitmap_tfz = wx.StaticBitmap(self.panel_1, -1, wx.Bitmap(os.path.join(self.icon_dir,"tfz.png"), wx.BITMAP_TYPE_ANY))
        self.button_index_html = wx.Button(self.panel_1, -1)
        self.button_dvd_explore = wx.Button(self.panel_1, -1)
        self.button_protext = [wx.Button(self.panel_1, -1)]
        if self.elevate:
            self.button_protext.append(wx.Button(self.panel_1, -1))

        self.button_protext_www = wx.Button(self.panel_1, -1)

        self.button_tl_install = [wx.Button(self.panel_1, -1, "Start TeX Live Installer")]
        if self.elevate:
            self.button_tl_install.append(wx.Button(self.panel_1, -1, "... as Administrator"))
        self.button_tl_advanced = [wx.Button(self.panel_1, -1, "Start TL Installer (ADVANCED)")]
        if self.elevate:
            self.button_tl_advanced.append(wx.Button(self.panel_1, -1, "... as Administrator"))
        self.button_tl_doc = wx.Button(self.panel_1, -1, "Open Documentation")
        self.button_tl_www = wx.Button(self.panel_1, -1, "Visit TeX Live in WWW")
        self.button_ctan_explore = wx.Button(self.panel_1, -1, "Explore CTAN snapshot")
        self.button_ctan_html = wx.Button(self.panel_1, -1)
        self.btn_exit = wx.Button(self.panel_1, -1, "Exit")

        self.UpdateLanguage(False)
        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_BUTTON, self.OnIndexHTML, self.button_index_html)
        self.Bind(wx.EVT_BUTTON, self.OnDVDExplore, self.button_dvd_explore)
        wx.EVT_MENU(self, ID_MENU_EXIT, self.OnExit)

        for button in self.button_protext:
            self.Bind(wx.EVT_BUTTON, self.OnProTeXt, button)
        self.Bind(wx.EVT_BUTTON, self.OnProTeXtWWW, self.button_protext_www)
        for button in self.button_tl_install:
            self.Bind(wx.EVT_BUTTON, self.OnTeXLive, button)
        for button in self.button_tl_advanced:
            self.Bind(wx.EVT_BUTTON, self.OnTeXLiveAdvanced, button)
        self.Bind(wx.EVT_BUTTON, self.OnTeXLiveDoc, self.button_tl_doc)
        self.Bind(wx.EVT_BUTTON, self.OnTeXLiveWWW, self.button_tl_www)
        self.Bind(wx.EVT_BUTTON, self.OnCTAN, self.button_ctan_explore)
        self.Bind(wx.EVT_BUTTON, self.OnCTANHTML, self.button_ctan_html)
        self.Bind(wx.EVT_BUTTON, self.OnExit, self.btn_exit)

    @property
    def isWin64(self):
        return 'PROGRAMFILES(X86)' in os.environ

    @property
    def windows_version(self):
        try:
            version = win32api.GetVersionEx()
            version = version[0]+0.001*version[1]
            #print version
            return version
        except Exception:
            return 0
    
    @property
    def is_elevated(self):
        ph = win32api.GetCurrentProcess()
        th = win32security.OpenProcessToken(ph,win32con.MAXIMUM_ALLOWED)
        is_elevated = win32security.GetTokenInformation(th,win32security.TokenElevation)
        is_elevated = bool(is_elevated)
        #print is_elevated
        return is_elevated
        
    def __cfg(self, section, key, default=None):
        try:
            return self.config.get(section, key)
        except ConfigParser.Error:
            return default

    def Execute(self, path, args="", **kwargs):
        if not os.path.exists(path):
            wx.MessageBox(_('File "%s" not found')%path, _("Configuration Error"), style=wx.OK|wx.ICON_ERROR, parent=self)
            return
        elevate = kwargs.get('elevate','ifneeded')
        action = "runas" if elevate=='always' else "open"
        try:
            shell.ShellExecuteEx(
                fMask = 0,
                nShow = win32con.SW_NORMAL,
                lpVerb = action,
                lpFile = path,
                lpDirectory = os.path.dirname(path),
                lpParameters = args
            )
        except pywintypes.error, error:
            if elevate=='ifneeded' and error.winerror==5:
                self.Execute(path, *args, elevate='always')
            else:
                msgbox = wx.MessageDialog(self,_("Running %s failed with the following error:")%" ".join([path,args])+"\n\n%s"%error.strerror,_("Error"), style=wx.OK|wx.CENTER|wx.ICON_ERROR)
                msgbox.ShowModal()
                msgbox.Destroy()
    def Explore(self,path):
        if os.path.isdir(path):
            os.startfile(path,"explore")
        else:
            wx.MessageBox(_('Directory "%s" not found')%path, _("Configuration Error"), style=wx.OK|wx.ICON_ERROR, parent=self)

    def UrlOpen(self, url):
        webbrowser.open(url)

    @classmethod
    def GetMainDir(cls):
        def main_is_frozen():
            return (hasattr(sys, "frozen") or # new py2exe
                     hasattr(sys, "importers")) # old py2exe
        if main_is_frozen():
           return os.path.dirname(sys.executable)
        return os.path.dirname(sys.argv[0])

    def __set_properties(self):
        self.SetTitle("TeX Collection %s"%self.year)
        self.label_title.SetFont(wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))

        if not self.ctan_dir:
            self.button_ctan_explore.Enable(False)
            self.button_ctan_html.Enable(False)
        if not self.tl_dir:
            for button in (self.button_tl_install+self.button_tl_advanced+[self.button_tl_doc]):
                button.Enable(False)
        if not self.protext_dir:
            for button in self.button_protext: button.Enable(False)

        icon = wx.Icon(os.path.join(self.icon_dir,"tex.ico"),wx.BITMAP_TYPE_ICO,16,16)
        self.SetIcon(icon)

    def __do_layout(self):
        sizer_top = wx.BoxSizer(wx.HORIZONTAL)
        sizer_main = wx.BoxSizer(wx.HORIZONTAL)
        sizer_right = wx.BoxSizer(wx.VERTICAL)
        sizer_ctan = wx.StaticBoxSizer(self.sizer_ctan_staticbox, wx.VERTICAL)
        sizer_texlive = wx.StaticBoxSizer(self.sizer_texlive_staticbox, wx.VERTICAL)
        sizer_protext = wx.StaticBoxSizer(self.sizer_protext_staticbox, wx.VERTICAL)
        sizer_left = wx.BoxSizer(wx.VERTICAL)
        sizer_dvd = wx.StaticBoxSizer(self.sizer_dvd_staticbox, wx.VERTICAL)
        sizer_left.Add(self.label_title, 0, 0, 0)
        sizer_left.Add((20, 10), 0, 0, 0)
        sizer_left.Add(self.bitmap_tfz, 0, 0, 0)
        sizer_left.Add((20, 10), 0, 0, 0)
        sizer_dvd.Add(self.button_index_html, 0, 0, 0)
        sizer_dvd.Add((5,5), 0, 0, 0)
        sizer_dvd.Add(self.button_dvd_explore, 0, 0, 0)
        sizer_left.Add(sizer_dvd, 0, wx.EXPAND, 0)
        if self.debug:
            sizer_left.Add(wx.StaticText(self, -1, 'DVD: %s'%str(self.dvd)))
            sizer_left.Add(wx.StaticText(self, -1, 'Windows-Version: %s'%str(self.windows_version)))
            sizer_left.Add(wx.StaticText(self, -1, '64bit: %s'%str(self.isWin64)))
            sizer_left.Add(wx.StaticText(self, -1, 'elevated: %s'%str(self.is_elevated)))
        sizer_main.Add(sizer_left, 0, wx.EXPAND, 0)
        sizer_main.Add((20, 20), 0, 0, 0)
        subsizer = wx.BoxSizer(wx.HORIZONTAL)
        for button in self.button_protext:
            subsizer.Add(button, 0, 0, 0)
        sizer_protext.Add(subsizer, 0, 0, 0)
        sizer_protext.Add((3,3), 0, 0, 0)
        subsizer = wx.BoxSizer(wx.HORIZONTAL)
        subsizer.Add(self.button_protext_www, 0, 0, 0)
        sizer_protext.Add(subsizer, 0, 0, 0)
        sizer_right.Add(sizer_protext, 0, wx.EXPAND, 0)
        sizer_right.Add((10,10), 0, 0, 0)
        subsizer = wx.BoxSizer(wx.HORIZONTAL)
        for button in self.button_tl_install:
            subsizer.Add(button, 0, 0, 0)
        sizer_texlive.Add(subsizer, 0, 0, 0)
        sizer_texlive.Add((2,2), 0, 0, 0)
        sizer_texlive.Add(self.button_tl_doc, 0, 0, 0)
        sizer_texlive.Add((5,5), 0, 0, 0)
        sizer_texlive.Add(self.button_tl_www, 0, 0, 0)
        sizer_texlive.Add((5,5), 0, 0, 0)
        subsizer = wx.BoxSizer(wx.HORIZONTAL)
        for button in self.button_tl_advanced:
            subsizer.Add(button, 0, 0, 0)
        sizer_texlive.Add(subsizer, 0, 0, 0)
        sizer_right.Add(sizer_texlive, 0, wx.EXPAND, 0)
        sizer_ctan.Add(self.button_ctan_explore, 0, 0, 0)
        sizer_ctan.Add((2,2), 0, 0, 0)
        sizer_ctan.Add(self.button_ctan_html, 0, 0, 0)
        sizer_right.Add((10,10), 0, 0, 0)
        sizer_right.Add(sizer_ctan, 0, wx.EXPAND, 0)
        sizer_right.Add((5,5), 0, 0, 0)
        subsizer = wx.BoxSizer(wx.HORIZONTAL)
        subsizer.Add((1,1), 1, wx.EXPAND, 0)
        subsizer.Add(self.btn_exit, 0, 0, 0)
        sizer_right.Add(subsizer, 0, wx.EXPAND, 0)
        sizer_main.Add(sizer_right, 0, wx.EXPAND, 0)
        self.panel_1.SetSizer(sizer_main)
        sizer_top.Add(self.panel_1, 0, wx.EXPAND, 0)
        self.SetSizer(sizer_top)
        sizer_top.Fit(self)
        self.Layout()

    def OnProTeXt(self, event): # wxGlade: MyFrame.<event_handler>
        source = event.GetEventObject()
        elevate = "ifneeded" if self.button_protext.index(source)==0 else "always"
        path = os.path.normpath(os.path.join(self.protext_dir,self.__cfg('proTeXt','setup','Setup.exe')))
        self.Execute(path,elevate=elevate)
        event.Skip()
    def OnProTeXtWWW(self, event): # wxGlade: MyFrame.<event_handler>
        self.UrlOpen(self.__cfg('proTeXt','url','http://tug.org/protext'))
        event.Skip()

    def OnTeXLive(self, event): # wxGlade: MyFrame.<event_handler>
        source = event.GetEventObject()
        index = self.button_tl_install.index(source)
        elevate = "ifneeded" if index==0 else "always"
        path = os.path.join(self.tl_dir,self.__cfg('TeXLive','install','install-tl.bat'))
        self.Execute(path,elevate=elevate)
        event.Skip()
    def OnTeXLiveAdvanced(self, event): # wxGlade: MyFrame.<event_handler>
        source = event.GetEventObject()
        index = self.button_tl_advanced.index(source)
        elevate = "ifneeded" if index==0 else "always"
        path = os.path.join(self.tl_dir,self.__cfg('TeXLive','advanced','install-tl-advanced.bat'))
        self.Execute(path,elevate=elevate)
        event.Skip()
    def OnTeXLiveDoc(self, event): # wxGlade: MyFrame.<event_handler>
        path = os.path.normpath(os.path.join(self.tl_dir,self.__cfg('TeXLive','doc','index.html')))
        self.Execute(path,elevate='never')
        event.Skip()
    def OnTeXLiveWWW(self, event): # wxGlade: MyFrame.<event_handler>
        self.UrlOpen(self.__cfg('TeXLive','url','http://tug.org/texlive/'))
        event.Skip()
    
    def OnCTAN(self, event): # wxGlade: MyFrame.<event_handler>
        self.Explore(self.ctan_dir)
        event.Skip()
    def OnCTANHTML(self, event): # wxGlade: MyFrame.<event_handler>
        lang = [items[1] for items in self.languages if items[0]==self.locale.GetLanguage()][0]
        path = os.path.normpath(os.path.join(self.ctan_dir,self.__cfg('CTAN','index_%s'%lang,'README.HTML')))
        if not os.path.exists(path) and not self.locale.GetName().startswith("en"):
            path = os.path.normpath(os.path.join(self.ctan_dir,self.__cfg('CTAN','index_en','README.HTML')))
        self.Execute(path, elevate='never')
        event.Skip()

    def OnIndexHTML(self, event): # wxGlade: MyFrame.<event_handler>
        lang = [items[1] for items in self.languages if items[0]==self.locale.GetLanguage()][0]
        path = os.path.normpath(os.path.join(self.dvd,self.__cfg('General','index_%s'%lang,'index.en.html')))
        if not os.path.exists(path) and not self.locale.GetName().startswith("en"):
            path = os.path.normpath(os.path.join(self.dvd,self.__cfg('General','index_en','index.en.html')))
        self.Execute(path, elevate='never')
        event.Skip()
    def OnDVDExplore(self, event): # wxGlade: MyFrame.<event_handler>
        path = os.path.normpath(self.dvd)
        self.Explore(path)
        event.Skip()

    def OnExit(self, event):
        event.Skip()
        sys.exit(0)

    def OnLanguageSelection(self, event):
        checked = [item for item in self.language_menu.GetMenuItems() if item.IsChecked()][0].GetId()
        #print checked
        self.language = [items[0] for items in self.languages if items[3]==checked][0]
        #print self.language
        self.UpdateLanguage()
        #event.Skip()
    def UpdateLanguage(self, redraw=True):
        if self.locale: del self.locale
        self.locale = wx.Locale(self.language)
        if not self.locale.IsOk():
            del self.locale
            self.locale = wx.Locale(self.languages[0][0])
        self.locale.AddCatalog('texcollection')
        if not self.locale.IsLoaded('texcollection'):
            del self.locale
            self.locale = wx.Locale(self.languages[0][0])
            self.locale.AddCatalog('texcollection')
        #print self.locale.GetName()
        #print self.locale.GetLanguage()
        
        lang, check_id = [(items[1],items[3]) for items in self.languages if items[0]==self.locale.GetLanguage()][0]
        #print check_id
        self.language_menu.FindItemById(check_id).Check(True)

        self.button_index_html.SetLabel(_("Open %s")%(self.__cfg('General','index_%s'%lang,'index.en.html').upper()))
        self.button_dvd_explore.SetLabel(_("Explore DVD"))
        self.button_protext[0].SetLabel(_("Open proTeXt"))
        try:
            self.button_protext[1].SetLabel(_("... as Administrator"))
        except IndexError:
            pass
        self.button_protext_www.SetLabel(_("Visit proTeXt in WWW"))
        self.button_tl_doc.SetLabel(_("Open TeX Live Documentation"))
        self.button_tl_install[0].SetLabel(_("Run TeX Live Installer"))
        try:
            self.button_tl_install[1].SetLabel(_("... as Administrator"))
        except IndexError:
            pass
        self.button_tl_advanced[0].SetLabel(_("Run TeX Live Installer (ADVANCED)"))
        try:
            self.button_tl_advanced[1].SetLabel(_("... as Administrator"))
        except IndexError:
            pass
        self.button_tl_www.SetLabel(_("Visit TeX Live in WWW"))
        
        self.button_ctan_explore.SetLabel(_("Explore CTAN snapshot"))
        self.button_ctan_html.SetLabel(_("Open %s")%(self.__cfg('CTAN','index_%s'%lang,'README.HTML').upper()))
        
        self.menubar.SetMenuLabel(0,_('File'))
        self.menubar.SetMenuLabel(1,_('Language')+("/Language" if not self.locale.GetName().startswith("en") else ""))
        self.btn_exit.SetLabel(_('Exit'))
        self.file_menu.SetLabel(ID_MENU_EXIT, _('Exit'))

        if redraw:
            self.GetSizer().Fit(self)
            self.Layout()
            self.Update()

# end of class MyFrame

if __name__ == "__main__":
    import optparse
    op = optparse.OptionParser()
    op.add_option("-d","--dir",dest="dir")
    options, args = op.parse_args()
    
    cp = ConfigParser.SafeConfigParser()
    cp.read([os.path.join(MyFrame.GetMainDir(),'lib','texcollection.ini')])
    app = wx.PySimpleApp(0)
    wx.InitAllImageHandlers()
    frame_main = MyFrame(None, -1, "", cfg=cp) if not options.dir else MyFrame(None, -1, "", dvd=options.dir, cfg=cp)
    app.SetTopWindow(frame_main)
    frame_main.Show()
    app.MainLoop()
