"""
     Copyright (C) 2007-2009 Franco Lanza <nextime@nexlab.it>
     Copyright (C) 2007-2009 Sandro Aliano <ita595@hotmail.com>
     Copyright (C) 2007-2009 Ivan Bellia <skylive@skylive.it>

     Web site: http://www.astronomix.org/trac/Skylive-NG

     This file is part of Skylive-NG.

     Skylive-NG is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
     (at your option) any later version.

     Skylive-NG is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with Skylive-NG.  If not, see <http://www.gnu.org/licenses/>.
"""


from skylive import config, conn, protocol
from skylive.utils import genutils as utils
import gui, imager, chatpriv, scriptsgui, liveduplicate, userinfo, booking
import downprog, fitsopener, info, focus
from skylive.lang import language
from settings import settings
from Pycard import model, dialog, timer, graphic
import wx, time, sys, os, platform
from cStringIO import StringIO
import Image, ImageOps, ImageDraw, ImageFile
import askstream, stream
import webbrowser, thread
from skylive.fits import fitsimage, levels
from twisted.internet import reactor
from skylive import chatparser as parser

class mainPanel(model.Background):

   photo = {'bin': False,
            'filter': False,
            'exp': False,
            'guide': "0",
            'web': "1",
            'aflat': "0",
            'adark': "0",
            'repeat': "0",
            'startn': "0"
           }

   chathtml = []
   photorun = False
   no_check_messier = False
   oldstatustext = ''
   inuserlist = False
   userlistbusy = False
   vercheckman  =  False
   closingclient = False
   username = 'unknown'
   focusdialog = False
   Streaming = False
   askStreaming = False
   StreamUri="http://skylive3.astronomix.org:8000/skylive.ogg"
   streamingIndex = 0
   latest = ''
   chatfontsize="1"

   def __init__(self, parent, rsrc):
      self.TwistedLoop = parent.TwistedLoop
      self.callInTwisted = parent.callInTwisted
      self.config = parent.config
      model.Background.__init__(self, parent, rsrc)

   def on_initialize(self, event):
      self.username = config.getUsername()
      #self.startSplash()
      sysType = utils.platform()
      if sysType == "Microsoft":
         #to fix some sVista
         self.systemType = "Windows"
      else:
         self.systemType = sysType
      if self.systemType ==  'Linux':
         if platform.system() != 'Linux':
            self.title = self.title.replace("Linux", platform.system())
      #config.initialize()
      self.privchats={}
      self.teleOn = False
      self.downPop = {}
      self.scriptguiStarted = False
      self.livedup = False
      self.initialized=False
      self.useExtProgram='False'
      self.useINDIProgram='False'
      self.StatusTextFormat("Inizializzazione in corso... / Initalizing...")
      self.ItemText = language.getItemText
      self.lang = config.get_usrLang()
      self.gui = 'skylive'
      self.setGui()
      self.SponsorCanvasFormat(self.getText('textHelpSkylive'))
      self.domeisopen=False
      self.resetARTargetReq = False
      self.lastPath = self.usrDefSavePath = config.get_usrDefaultPath()
      self.charSizes = config.get_usrCharSizes()
      self.useExtProgram = config.get_extProgram()
      self.useINDIProgram = config.get_extINDIProgram()
      self.enableStream, self.askStream=config.get_streamingPref()
      self.streamingIndex=config.get_streamingIndex()
      self.defaultPointerColor = config.get_usrPointerColor()
      self.forcedLowRes = config.get_lowResPref()
      print 'Forced lowRes : ',self.forcedLowRes
      self.setCharSizes()
      self.resetPhotos()
      self.custom_fn=False
      self.starsSetted=False
      self.doubleSetted=False
      self.TscopeComboSetted=False
      self.adminPrivilege = False
      self.telescopesel=1
      self.srvproto = protocol.ServerComm(self)
      self.srvproto.AuthString(str(config.getUsername()), str(config.getPassword()))
      self.serveraddr = "skylive.astronomix.org"
      self.setGUImenus()
      self.TwistedLoop.imgDownloader('start')
      self.setStatus()
      self.scriptReset()
      self.scriptSep = "*"
      self.components.PathField.text = self.usrDefSavePath
      self.on_SelectTarget()
      self.StatusTextFormat("Connessione al server in corso... / Connecting to server...")
      self.connLoose = False
      self.connect(self.serveraddr)
      self.resetCiceroneMode()
      self.canSelect = False
      self.downloadedBits = []
      self.config = config
      self.initialized = True
      if self.systemType == "Windows" and self.useExtProgram == 'True':
         self.startFake()
      if self.useINDIProgram == 'True':
         self.startINDI()
      #self.stopSplash()
      self.eventTimer = timer.Timer(self.components.StatusText, -1)
      self.eventTimer.Start(1000)
      self.visible=True
      self.TwistedLoop.checkUpgrade()
      # Temporanei!
      self.MenuBar.setEnabled('menuBooking', False)
      self.MenuBar.setEnabled('menuAccount', False)

   def scriptReset(self):
      self.scripts=[]
      self.scripts_count=0
   
   def on_setStreamIdx(self, idx):
      config.set_streamingIndex(idx)

   def on_setMyUsername(self, username):
      self.username = username

   def on_menuCheckVersion_select(self, event):
      try:
         self.TwistedLoop.checkUpgrade(False)
         self.vercheckman = True
      except:
         pass

   def upgradeDownloadFailed(self):
      self.alertDialog(self.getText("upgradeFailed"))

   def on_versionCheck(self, mver, nver, upuri, nvermd5):
      if int(mver) < int(nver):

         import gui
         res = gui.Upgrade()
         if res == 'UPGRADE':
            if utils.is_frozen():
               if platform.system() in ['Windows', 'Microsoft']:
                  self.TwistedLoop.downloadUpgrade(upuri, nvermd5)
               elif platform.system() == 'Linux':
                  self.TwistedLoop.downloadUpgrade(upuri, nvermd5)
               elif platform.system() == 'Darwin':
                  self.TwistedLoop.downloadUpgrade(upuri, nvermd5)
               else:
                  self.alertDialog(self.getText("clientVerSources"))
            else:
               self.alertDialog(self.getText("clientVerSources"))
               #self.TwistedLoop.downloadUpgrade(upuri, nvermd5)
            
         elif res == 'LATERUPGRADE':
            pass
         elif res == 'NOUPGRADE':
            if not self.vercheckman:
               self.TwistedLoop.stopCheckUpgrade()

         self.vercheckman = False
      else:
         if self.vercheckman:
            self.vercheckman = False
            self.alertDialog(self.getText("clientUpdated"))

   def on_StatusText_timer(self, event):
      if self.photorun:
         try:
            rem = int(self.photorun['data'][4])
            nick = self.photorun['data'][0]
            filter = self.photorun['data'][1]
            bin =  self.photorun['data'][2]
            exp = int(self.photorun['data'][3])
            p = self.getText('statusPhoto')
            f = self.getText('statusFilter')
            e = self.getText('statusRemain')
            u = self.getText('statusUpload')
            if self.photorun['status'] == 'up':
               status = u+" *"+str(nick)+"* tot exp: "+str(exp)+" sec., "+f+": "+str(filter)
               status += ", bin: "+str(bin)+", "+e+": "+str(rem)+" sec." 
               self.StatusTextFormat(status, photo=True)
            elif self.photorun['status']  == 'run':
               status = p+" *"+str(nick)+"* tot exp: "+str(exp)+" sec., "+f+": "+str(filter)
               status += ", bin: "+str(bin)+", "+e+": "+str(rem)+" sec."
               self.StatusTextFormat(status, photo=True)
            if int(rem) > 0:
               self.photorun['data'][4] = int(rem)-1
         except:
            pass


   def on_setExposureUpload(self, data):
      #print 'on_setExposureUpload'
      self.photorun = {
                        'status': 'up',
                        'data': data
                      }



   def on_setExposureRunning(self, data):
      #print 'on_setExposureRunning'
      self.photorun = {
                        'status': 'run',
                        'data': data
                      }


   def on_setExposureNone(self, event=None):
      #print 'on_setExposureNone'
      self.photorun = False
      ra = self.components.TelescopeRAText.text
      dec = self.components.TelescopeDECText.text
      status = self.oldstatustext
      self.StatusTextFormat(status, ra, dec)

   def on_idle(self, event):
      # Save CPU load
      if self.systemType == "Windows":
         time.sleep(.03)

   def on_menuFileExit_select(self, event):
      self.on_close(event)

   def on_close(self, event):
      try:
         self.eventTimer.Stop()
      except:
         pass
      try:
         event.skip()
      except:
         pass
      self.StatusTextFormat("Chiusura in corso... / Closing...")
      if not self.connLoose and not self.closingclient:
         self.closingclient = True
         try:
            self.TwistedLoop.imgDownloader('stop')
            self.TwistedLoop.serverDisconnect()
         except:
            pass
      # XXX Shuld exit also from the twisted loop, but, in effect,
      # sometimes this won't happen. As we are a GUI only app,
      # temporarely the work around for this issue is to simply call
      # sys.exit() here. Sometime in a future release we will fix this in a
      # better way.
      #if self.closingclient:
      #   import sys
      #   sys.exit(0)
      if self.closingclient:
         self.TwistedLoop.forcedExit()
         reactor.pycard_is_stopping = True
      # XXX Sometime windows won't close cleany. Fuck.
      if platform.system() in ['Windows', 'Microsoft']:
         sys.exit(0)


   def on_StopClient(self, event=True):
      self.connLoose = False
      self.on_close(event)

   def connect(self, ip, timeout=0):
      #XXX bisogna specificare il tipo di connessione!
      #print 'CONNECT'
      self.TwistedLoop.serverConnect(ip, timeout)
   
   def startFake(self):
      print 'avvio fakedriver'
      self.TwistedLoop.startFakeDriver()
   
   def stopFake(self):
      print 'fermo fakedriver'
      self.TwistedLoop.stopFakeDriver()

   def startINDI(self):
      self.TwistedLoop.startINDIDriver()

   def stopINDI(self):
      self.TwistedLoop.stopINDIDriver()

   def on_LoseConnection(self, reconnect=False):
      # XXX gestire una chiamata qui quando ci disconnettiamo!
      self.connLoose = True
      self.ciceroneMode = False
      try:
         self.StatusTextFormat("Disconnesso dal server in corso.../Disconnected from the server...")
      except:
         pass
      if reconnect:
         try:
            self.StatusTextFormat("Riconnessione al server in corso.../Reconnecting to server...")
         except:
            pass
         self.connect(self.serveraddr, 2)
      else:
         try:
            self.close()
         except:
            pass


   def on_callback(self, cmd):
      for key in cmd:
         f=getattr(self, 'on_'+key, None)
         if f and callable(f):
            f(cmd[key])

   def notImplemented(self):
      self.alertDialog("Not yet implemented, sorry!")

   def alertDialog(self, msg):
      dialog.alertDialog(self, msg)

   def setStatus(self, tscope=1):
      self.TwistedLoop.changeTelescope(tscope)

   def setGUImenus(self):
      self.setPlanetsList()
      self.setMessierList()
      self.setNGCList()
      self.setICList()
      self.resetARTarget()

   def on_MakePhoto_mouseClick(self, event):
      if self.photo['bin'] and self.photo['filter'] and self.photo['exp']:
         # XXX popups etc
         # XXX gestire il repeat
         # XXX gestire lo stop photo ( cambiare il text sul tasto? )
         photostring = self.srvproto.makePhoto(self.photo['exp'], self.photo['filter'],
                                               self.photo['guide'], self.photo['bin'],
                                               self.photo['aflat'], self.photo['adark'],
                                               self.photo['web'])
         if photostring:
            #self.callInTwisted('sendNetworkData', photostring)
            self.TwistedLoop.sendNetworkData(photostring)
            if self.components.CheckBoxWeb.checked:
               self.photoKeyClick = True
        
      else:
         # XXX mettere un avviso
         pass

   def resetPhotos(self):
      self.photo = {'bin': False, 
                    'filter': False, 
                    'exp': False,
                    'guide': "0",
                    'web': "1",
                    'aflat': "0",
                    'adark': "0",
                    'repeat': "0",
                    'startn': "0"
                    }
      self.components.SpinnerExposition.value=0
      self.components.ComboBin.text="X"
      self.components.ComboFilters.text="X"
      self.components.CheckBoxAutoflat.checked=False
      self.components.CheckBoxWeb.checked=True
      self.components.CheckBoxGuide.checked=False
      self.components.CheckBoxAutodark.checked=False
      self.components.SpinnerRepeat.value=0
      self.photoKeyClick = False
      self.photoInUpload = False
      

   def on_SpinnerExposition_textUpdate(self, event):
      if self.initialized:
         exp = self.components.SpinnerExposition.value
         try:
            if int(exp) in range(0, 901):
               exptime = exp
               #print "EXP: "+str(exp)
            elif int(exp) > 900:
               exptime = 900
               self.components.SpinnerExposition.value = 900
            else:
               exptime = 0
         except:
            exptime = 0
            self.components.SpinnerExposition.value = 0
         self.photo['exp'] = str(exptime)
         self.createFileName()

   def on_SpinnerExposition_loseFocus(self, event):
      if not self.components.SpinnerExposition.value:
         self.components.SpinnerExposition.value = 0
         self.photo['exp'] = False
         self.createFileName()
      event.skip()

   def on_ComboBin_textUpdate(self, event):
      if self.initialized:
         bin = self.components.ComboBin.text
         bins = "123"
         if bin in bins and len(bin) == 1:
            binsel = bin
            self.components.ComboBin.text = str(bin)
         else:
            binsel = "X"
            self.components.ComboBin.text = ""
         self.photo['bin'] = str(binsel)
         self.createFileName()
   
   def on_ComboBin_loseFocus(self, event):
      if not self.components.ComboBin.text:
         self.components.ComboBin.text = 'X'
         self.photo['bin'] = False
         self.createFileName()
      event.skip()

   def on_ComboFilters_textUpdate(self, event):
      filt = self.components.ComboFilters.text
      filters = str(self.components.TelescopeFiltersText.text)
      if filt in filters:# and len(filt) == 1:
         selfilt = filt
      else:
         selfilt = "X"
         self.components.ComboFilters.text = "X"
      self.photo['filter'] = selfilt
      self.createFileName()
   
   def on_ComboFilters_loseFocus(self, event):
      if not self.components.ComboFilters.text:
         self.components.ComboFilters.text = "X"
         self.photo['filter'] = False
         self.createFileName()
      event.skip()

   def on_SpinnerRepeat_textUpdate(self, event):
      if self.initialized:
         rep = self.components.SpinnerRepeat.value
         try:
            if int(rep) > 0 and int(rep) < 501:
               reptime = rep
            elif int(rep) > 501:
               reptime = 500
               self.components.SpinnerRepeat.value = 500
            else:
               reptime = 0
         except:
            reptime = 0
            self.components.SpinnerRepeat.value=0
         self.photo['repeat'] = str(reptime)
   
   def on_SpinnerRepeat_loseFocus(self, event):
      if not self.components.SpinnerRepeat.value:
         self.components.SpinnerRepeat.value = 0
         self.photo['repeat'] = '0'
      event.skip()

   def on_Spinner1_textUpdate(self, event):
      self.photo['startn'] = self.components.Spinner1.value

   def on_CheckBoxAutoflat_mouseClick(self, event):
      if self.components.CheckBoxAutoflat.checked:
         self.photo['aflat'] = "1"
      else:
         self.photo['aflat'] = "0"

   def on_CheckBoxWeb_mouseClick(self, event):
      if self.components.CheckBoxWeb.checked:
         self.photo['web'] = "1"
      else:
         self.photo['web'] = "0"

   def on_CheckBoxGuide_mouseClick(self, event):
      if self.components.CheckBoxGuide.checked:
         self.photo['guide'] = "1"
      else:
         self.photo['guide'] = "0"

   def on_CheckBoxAutodark_mouseClick(self, event):
      if self.components.CheckBoxAutodark.checked:
         self.photo['adark'] = "1"
      else:
         self.photo['adark'] = "0"

   def setStarsList(self):
      x = self.starlist.keys()
      x.sort()
      for item in x:
         if len(item) > 0:
            self.components.ComboStars.append(item)
      self.components.ComboStars.text="Select"

   def setDoublesList(self):
      x = self.doublelist.keys()
      x.sort()
      for item in x:
         if len(item) > 0:
            self.components.ComboDouble.append(item)
      self.components.ComboDouble.text="Select"

   def setPlanetsList(self):
      for item in ["Mercury", "Venus", "Moon", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto" ]:
         self.components.ComboPlanets.append(item)
      self.components.ComboPlanets.text="Select"

   def setMessierList(self):
      for m in xrange(1, 111):
         self.components.ComboMessier.append("M%d" % m)
      self.components.ComboMessier.text="Select"


   def setNGCList(self):
      self.components.SpinnerNGC.value=0

   def setICList(self):
      self.components.SpinnerIC.value=0

   def on_ComboPlanets_textUpdate(self, event):
      #This is a bad hack to prevent text writed into combo field
      CPlanets = self.components.ComboPlanets.text.replace('Select', '')
      if not CPlanets in self.components.ComboPlanets.items:
         self.components.ComboPlanets.text = "Select"
         self.on_SelectTarget('Planets', False)
      else:
         self.on_SelectTarget('Planets', CPlanets)
         self.components.ComboPlanets.text = CPlanets

   def on_ComboMessier_textUpdate(self, event):
      if self.initialized:
         mt = str(self.components.ComboMessier.text)
         if mt != "Select" and not self.no_check_messier:
            m = mt.replace('M', '').replace('m', '')
            try:
               if int(m) > 0 and int(m) < 111:
                  messier = "M"+str(m)
               elif int(m) > 111:
                  messier = "M110"
                  self.no_check_messier = True
                  self.components.ComboMessier.text = str(messier)
               else:
                  self.components.ComboMessier.text = ''
                  messier = 0
            except:
               self.components.ComboMessier.text = ''
               messier = 0
            if messier != 0:
               self.on_SelectTarget('Messier', str(messier))
         else:
            self.no_check_messier = False

   def on_ComboMessier_loseFocus(self, event):
      if not self.components.ComboMessier.text:
         self.components.ComboMessier.text = 'Select'
      else:
         if 'M' not in self.components.ComboMessier.text:
            text = self.components.ComboMessier.text
            if text != 'Select':
               newtext = 'M'+text
               self.components.ComboMessier.text = newtext
            else:
               self.components.ComboMessier.text = 'Select'
      event.skip()

   def on_ComboStars_textUpdate(self, event):
      CStars = self.components.ComboStars.text.replace('Select', '')
      if not CStars in self.components.ComboStars.items:
         self.components.ComboStars.text = "Select"
         self.on_SelectTarget('Stars', False)
      else:
         self.on_SelectTarget('Stars', CStars)
         self.components.ComboStars.text = CStars

   def on_SpinnerNGC_loseFocus(self, event):
      ngc = str(self.components.SpinnerNGC.value)
      if ngc != '0':
         self.on_SelectTarget('NGC', ngc)
      else:
         pass
      event.skip()

   def on_ComboDouble_textUpdate(self, event):
      CDStars = self.components.ComboDouble.text.replace('Select', '')
      if not CDStars in self.components.ComboDouble.items:
         self.components.ComboDouble.text = "Select"
         self.on_SelectTarget('Double', False)
      else:
         self.on_SelectTarget('Double', CDStars)
         self.components.ComboDouble.text = CDStars
   
   def on_SpinnerIC_loseFocus(self, event):
      ic = str(self.components.SpinnerIC.value)
      if ic  !=  '0':
         self.on_SelectTarget('IC', ic)
      else:
         pass
      event.skip()

   def on_SelectTarget(self, type=None, which=None):
      self.selectedTarget=[None, None]
      done=False
      for t in ['Planets', 'Messier', 'Stars', 'Double']:
         if t != type:
            f=getattr(self.components, 'Combo'+t, None)
            if f:
               f.text = 'Select'
         else:
            if type:
               self.selectedTarget=[type, which]
               done=True

      if not done:
         if type and type == 'NGC' and which != '0':
            self.selectedTarget=['NGC', which]
            self.resetARTarget()
            self.setICList()
         elif type and type == 'IC' and which != '0':
            self.selectedTarget=['IC', which]
            self.resetARTarget()
            self.setNGCList()
         elif type and type == 'AR':
            self.selectedTarget=['AR', which]
            self.setICList()
            self.setNGCList()
         else:
            self.setICList()
            self.resetARTarget()
            self.setNGCList()
      else:
         self.resetARTarget()
         self.setNGCList()
         self.setICList()
   

   def resetARTarget(self):
      self.resetARTargetReq = True
      self.components.PointRA1.text='00'
      self.components.PointRA2.text='00'
      self.components.PointRA3.text='0'
      self.components.PointDEC1.text='+'
      self.components.PointDEC2.text='00'
      self.components.PointDEC3.text='00'
      self.resetARTargetReq = False

   def on_PointRA1_keyPress(self, event):
      key = event.GetKeyCode()
      chars = [wx.WXK_TAB,wx.WXK_ESCAPE,wx.WXK_DELETE,wx.WXK_CANCEL,wx.WXK_BACK,wx.WXK_RETURN]
      if (((key >= 48) and  (key <= 57)) or (key in chars)):
         event.skip()

   def on_PointRA1_loseFocus(self, event):
      if not self.resetARTargetReq:
         maxlen = 2
         text = self.components.PointRA1.text
         if len(text) > maxlen:
            text = text[:maxlen]
         if text != "" and int(text) > 23:
            text = "23"
         text = text.zfill(maxlen)
         self.resetARTargetReq = True
         self.components.PointRA1.text=str(text)
         self.resetARTargetReq = False
         self.on_setARDECTarget()

   def on_PointRA2_keyPress(self, event):
      key = event.GetKeyCode()
      chars = [wx.WXK_TAB,wx.WXK_ESCAPE,wx.WXK_DELETE,wx.WXK_CANCEL,wx.WXK_BACK,wx.WXK_RETURN]
      if (((key >= 48) and  (key <= 57)) or (key in chars)):
         event.skip()

   def on_PointRA2_loseFocus(self, event):
      if not self.resetARTargetReq:
         maxlen = 2
         text = self.components.PointRA2.text
         if len(text) > maxlen:
            text = text[:maxlen]
         if text != "" and int(text) > 59:
            text = "59"
         text = text.zfill(maxlen)
         self.resetARTargetReq = True
         self.components.PointRA2.text=str(text)
         self.resetARTargetReq = False
         self.on_setARDECTarget()

   def on_PointRA3_keyPress(self, event):
      key = event.GetKeyCode()
      chars = [wx.WXK_TAB,wx.WXK_ESCAPE,wx.WXK_DELETE,wx.WXK_CANCEL,wx.WXK_BACK,wx.WXK_RETURN]
      if (((key >= 48) and  (key <= 57)) or (key in chars)):
         event.skip()

   def on_PointRA3_loseFocus(self, event):
      if not self.resetARTargetReq:
         maxlen = 1
         text = self.components.PointRA3.text
         if len(text) > maxlen:
            text = text[:maxlen]
         if text != "" and int(text) > 9:
            text = "9"
         text = text.zfill(maxlen)
         self.resetARTargetReq = True
         self.components.PointRA3.text=str(text)
         self.resetARTargetReq = False
         self.on_setARDECTarget()

   def on_PointDEC1_keyPress(self, event):
      key = event.GetKeyCode()
      chars = [wx.WXK_TAB,wx.WXK_ESCAPE,wx.WXK_DELETE,wx.WXK_CANCEL,wx.WXK_BACK,wx.WXK_RETURN,43,45]
      if key in chars:
         event.skip()

   def on_PointDEC1_loseFocus(self, event):
      if not self.resetARTargetReq:
         maxlen = 1
         text = self.components.PointDEC1.text
         if len(text) > maxlen:
            text = text[:maxlen]
         if text == "":
            text = "+"
         self.resetARTargetReq = True
         self.components.PointDEC1.text=str(text)
         self.resetARTargetReq = False
         self.on_setARDECTarget()

   def on_PointDEC2_keyPress(self, event):
      key = event.GetKeyCode()
      chars = [wx.WXK_TAB,wx.WXK_ESCAPE,wx.WXK_DELETE,wx.WXK_CANCEL,wx.WXK_BACK,wx.WXK_RETURN]
      if (((key >= 48) and  (key <= 57)) or (key in chars)):
         event.skip()

   def on_PointDEC2_loseFocus(self, event):
      if not self.resetARTargetReq:
         maxlen = 2
         text = self.components.PointDEC2.text
         if len(text) > maxlen:
            text = text[:maxlen]
         if text != "" and int(text) > 89:
            text = "89"
         text = text.zfill(maxlen)
         self.resetARTargetReq = True
         self.components.PointDEC2.text=str(text)
         self.resetARTargetReq = False
         self.on_setARDECTarget()

   def on_PointDEC3_keyPress(self, event):
      key = event.GetKeyCode()
      chars = [wx.WXK_TAB,wx.WXK_ESCAPE,wx.WXK_DELETE,wx.WXK_CANCEL,wx.WXK_BACK,wx.WXK_RETURN]
      if (((key >= 48) and  (key <= 57)) or (key in chars)):
         event.skip()

   def on_PointDEC3_loseFocus(self, event):
      if not self.resetARTargetReq:
         maxlen = 2
         text = self.components.PointDEC3.text
         if len(text) > maxlen:
            text = text[:maxlen]
         if text != "" and int(text) > 99:
            text = "99"
         text = text.zfill(maxlen)
         self.resetARTargetReq = True
         self.components.PointDEC3.text=str(text)
         self.resetARTargetReq = False
         self.on_setARDECTarget()

   def on_setARDECTarget(self):
      ra1=self.components.PointRA1.text
      ra2=self.components.PointRA2.text
      ra3=self.components.PointRA3.text
      dec1=self.components.PointDEC1.text
      dec2=self.components.PointDEC2.text
      dec3=self.components.PointDEC3.text
      if ra1!="00" or ra2!="00" or ra3!="0" or dec2!="00" or dec3!="00":
         artarget=ra1+":"+ra2+"."+ra3+dec1+dec2+":"+dec3
         self.on_SelectTarget('AR', artarget)
         #print artarget


   def on_PointGOTO_mouseClick(self, event):
      try:
         pointstring = self.srvproto.moveToTarget(self.selectedTarget)
      except:
         pointstring = False

      if pointstring:
         self.TwistedLoop.sendNetworkData(pointstring)

   def on_LastPhoto_mouseClick(self, event):
      self.TwistedLoop.getLastPhoto()

   def on_LastPhotoDone(self, photo):
      nolog = wx.LogNull()
      sysType = self.systemType
      if not os.path.exists(os.path.normpath("./gui/imager."+sysType+".rsrc.py")):
         sysType = "Linux"
      self.LastPhotoImager = model.childWindow(self, imager.SkyliveImager, "./gui/imager."+sysType+".rsrc.py")
      lfsize= self.LastPhotoImager.size
      self.LastPhotoImager.SetMaxSize(lfsize)
      self.LastPhotoImager.SetMinSize((lfsize))
      self.LastPhotoImager._parent = self
      self.LastPhotoImager.parent = self
      posX = self.position[0]+(self.size[0]/2)-(self.LastPhotoImager.size[0]/2)
      posY = self.position[1]+(self.size[1]/2)-(self.LastPhotoImager.size[1]/2)
      self.LastPhotoImager.position = (posX, posY)
      self.LastPhotoImager.visible = True
      self.LastPhotoImager.title = self.getText('lastphototitle')+str(self.telescopesel)
      newBitmap = graphic.Bitmap()
      newBitmap.setImageBits(wx.ImageFromStream(StringIO(photo)))
      self.LastPhotoImager.components.ImageShow.bitmap = newBitmap
      self.LastPhotoImager.telescope=self.telescopesel
      self.LastPhotoImager.components.ButtonClose.visible = True
      self.LastPhotoImager.components.ButtonDownload.visible = True
      self.LastPhotoImager.fromEvent = "lastphoto"
      self.LastPhotoImager.visible = True
      del nolog

   def on_FitsDownloaded(self, fitpath):
      sysType = self.systemType
      if not os.path.exists(os.path.normpath("./gui/imager."+sysType+".rsrc.py")):
         sysType = "Linux"
      self.FitsImager = model.childWindow(self, imager.SkyliveImager, "./gui/imager."+sysType+".rsrc.py")
      self.FitsImager._parent = self
      posX = self.position[0]+(self.size[0]/2)-(self.FitsImager.size[0]/2)
      posY = self.position[1]+(self.size[1]/2)-(self.FitsImager.size[1]/2)
      self.FitsImager.position = (posX, posY)
      self.FitsImager.title = self.getText('fitviewertitle')

      # if we remove the fits file, the viewer can't save it how is
      # implemented now
      fitsfile = fitsimage.FitsImage(fitpath, False, self.forcedLowRes)
      scidata = fitsfile.image
      self.autoMax = fitsfile.autoMaxLevel
      self.autoMin = fitsfile.autoMinLevel
      self.fitsHeader = fitsfile.headers.ascardlist()
      self.FitsImager.pilImage = fitsfile.pilImage
      image = wx.EmptyImage(fitsfile.xsizeBit, fitsfile.ysizeBit)
      self.xsizeBit = fitsfile.xsizeBit
      self.ysizeBit = fitsfile.ysizeBit
      image.SetData(fitsfile.pilImage.convert("RGB").tostring())
      self.imageBitmap = graphic.Bitmap()
      self.imageBitmap.setImageBits(image)
      self.FitsImager.components.ImageShow.bitmap = self.imageBitmap
      self.FitsImager.size = (fitsfile.xsizeBit+20, fitsfile.ysizeBit+100)

      if fitsfile.pilResized:
         self.FitsImager.title = self.getText('fitimagertitle1')+str(fitsfile.percresize)+self.getText('fitimagertitle2')
      oxc, oyc = self.FitsImager.components.ButtonClose.position
      oxs, oys = self.FitsImager.components.ButtonSave.position
      oxp, oyp = self.FitsImager.components.ButtonCompare.position
      oxz, oyz = self.FitsImager.components.ButtonSaveAs.position
      self.FitsImager.components.ButtonClose.position = (oxc, oyc-240+int(fitsfile.ysizeBit))
      self.FitsImager.components.ButtonSave.position = (oxs, oys-240+int(fitsfile.ysizeBit))
      self.FitsImager.components.ButtonCompare.position = (oxp, oyp-240+int(fitsfile.ysizeBit))
      self.FitsImager.components.ButtonSaveAs.position = (oxz, oyz-240+int(fitsfile.ysizeBit))
      self.FitsImager.components.ButtonSaveAs.visible = True
      self.FitsImager.components.ButtonClose.visible = True
      self.FitsImager.components.ButtonSave.visible = True
      if fitsfile.canCompare:
         self.FitsImager.components.ButtonCompare.visible = True
         self.FitsImager.imageData = [fitsfile.ra, fitsfile.dec, fitsfile.xfield, fitsfile.yfield]

      self.FitsImager.fromEvent = "photodown"
      
      try:
         # this catch an exception in wxPython 2.6. Uhmm but it seem to work.
         self.FitsImager.menuBar.setEnabled('menuPhoto', True)
      except:
         pass
      self.FitsImager.fitfile = fitpath
      self.FitsImager.origImage = [fitsfile.pilOrI, fitsfile.xsizeBit, fitsfile.ysizeBit, 
                                   fitsfile.min , fitsfile.max, fitsfile.med, 
                                   fitsfile.pilRaw, fitsfile.pilResized]
      self.FitsImager.visible = True
      self.FitsImager.refresh()
      self.FitsImager.on_adjust_command()

   def on_BigLive_mouseClick(self, event):
      self.on_LiveDuplicate(event)

   def on_CCDTemp(self, temp):
      self.components.TelescopeCCDTempText.text=str(temp)

   def on_setLiveImage(self, image):
      nolog = wx.LogNull()
      try:
      #if True:
         if self.addCross:
            self.drawCross(image, self.ciceronePosx, self.ciceronePosy)
         else:
            newBitmap = graphic.Bitmap()
            wximage = wx.ImageFromStream(StringIO(image))
            w, h = wximage.GetSize()
            if(int(w) != 320) or (int(h) != 240):
               wximage.Rescale(320, 240)
            newBitmap.setImageBits(wximage)
            self.components.Live640.bitmap = newBitmap
            #self.components.Live640.SetBitmap(wx.BitmapFromImage(wximage))
            self.liveBitmap = newBitmap
         if self.ciceroneMode and self.resendCrossC:
            self.resendCross()
         if self.livedup:
            self.livedup.setLiveImage(self.components.Live640.bitmap)
      except:
         pass
      del nolog

   def on_setGuideImage(self, image):
      nolog = wx.LogNull()
      try:
         newBitmap = graphic.Bitmap()
         newBitmap.setImageBits(wx.ImageFromStream(StringIO(image)))
         self.components.GuideImage.bitmap = newBitmap
      except:
         pass
      del nolog

   def on_TScopeCombo_select(self, event):
      telscopesel = int(event.selection)+1
      event.skip()
      self.TelescopeChange(telscopesel)

   def TelescopeChange(self, telscopesel):
      self.photorun = False
      self.ciceroneMode = False
      self.TwistedLoop.sendNetworkData(self.srvproto.changeTelescope(str(telscopesel)))
      self.setStatus(telscopesel)

      self.telescopesel = telscopesel
      # Reset the pointing menus
      self.on_SelectTarget()
      # reset the Photo configs
      self.resetPhotos()

   def changeFilters(self, filters):
      self.components.ComboFilters.items = []
      for filter in filters:
         self.components.ComboFilters.append(filter)
      self.components.ComboFilters.text = "X"

   def StatusTextFormat(self, text="", ra="-", dec="-", photo=False):
      canvas = self.components.StatusText
      canvas.foregroundColor='white'
      canvas.backgroundColor='blue'
      canvas.clear()
      canvas.fillColor='BLACK'
      canvas.drawText("Status: "+text, (5,1))
      if not photo:
         self.oldstatustext = text
         self.components.TelescopeRAText.text=ra
         self.components.TelescopeDECText.text=dec
         if self.systemType == "Windows":
            self.writeARDEC(ra, dec)
         self.writeARDECIndi(ra, dec)


   def SponsorCanvasFormat(self, text=""):
      c = self.components.SponsorCanvas
      c.foregroundColor='white'
      c.backgroundColor='blue'
      c.clear()
      c.fillColor='BLACK'
      c.drawText(text, (5,1))

   def on_setError(self, err):
      Xerr=err[0]
      Yerr=err[1]
      self.components.XerrText.text=Xerr
      self.components.YerrText.text=Yerr

   def on_updateUserList(self, userlist):
      self.components.UserlistArea.Clear()
      self.components.UserlistArea.insertItems(userlist[:-1], 0)
      last = int(self.components.UserlistArea.getCount())
      #self.components.UserlistArea.delete(last-1)

   def on_UserlistArea_mouseContextUp(self, event):
      sel = self.components.UserlistArea.GetSelections()
      if len(sel) > 0:
         toadmin = False
         touser = self.components.UserlistArea.getString(sel[0])
         self.chat_message_tocomp = touser
         if touser[:1] == '@' or touser[:1] == '>' or touser[:1] == "!":
            if touser[:1] == "!":
               toadmin = True
            touser = touser[1:]
         self.chat_message_to = touser
         if config.getUsername() != touser:
            relX, relY = event.GetPosition()
            fX, fY = self.components.UserlistArea.position
            self.popupID1 = wx.NewId()
            self.Bind(wx.EVT_MENU, self.on_PrivMesgClick, id=self.popupID1)
            menu = wx.Menu()
            menu.Append(self.popupID1, self.getText('privMenu'))
            if self.adminPrivilege and not toadmin:
               self.popupID2 = wx.NewId()
               self.Bind(wx.EVT_MENU, self.on_KillUserClick, id=self.popupID2)
               menu.Append(self.popupID2, 'Kill')
               self.popupID3 = wx.NewId()
               self.Bind(wx.EVT_MENU, self.on_MuteUserClick, id=self.popupID3)
               menu.Append(self.popupID3, 'Mute')
               self.popupID4 = wx.NewId()
               self.Bind(wx.EVT_MENU, self.on_BanUserClick, id=self.popupID4)
               menu.Append(self.popupID4, 'Ban')
               self.popupID5 = wx.NewId()
               self.Bind(wx.EVT_MENU, self.on_StopUserClick, id=self.popupID5)
               menu.Append(self.popupID5, 'Stop')
            self.PopupMenu(menu, (relX+fX, relY+fY))
            menu.Destroy

   def on_KillUserClick(self, event):
      self.TwistedLoop.sendNetworkData(self.srvproto.KillUser(self.chat_message_to))
   
   def on_MuteUserClick(self, event):
      self.TwistedLoop.sendNetworkData(self.srvproto.MuteUser(self.chat_message_to))

   def on_BanUserClick(self, event):
      self.TwistedLoop.sendNetworkData(self.srvproto.BanUser(self.chat_message_to))

   def on_StopUserClick(self, event):
      self.TwistedLoop.sendNetworkData(self.srvproto.StopUser(self.chat_message_to))


   def on_PrivMesgClick(self, event):
      if not self.chat_message_to in self.privchats:
         self.privchats[self.chat_message_to] = model.childWindow(self, chatpriv.ChatPrivate, "./gui/chatpriv.rsrc.py")
         self.privchats[self.chat_message_to].touser = self.chat_message_to
         self.privchats[self.chat_message_to].tousercomp = self.chat_message_tocomp
         self.privchats[self.chat_message_to].title = self.getText('privTitle')+self.chat_message_to
         self.privchats[self.chat_message_to]._parent = self
         self.privchats[self.chat_message_to].components.Send.label = self.getText('privSendButton')
         posX = self.position[0]+(self.size[0]/2)-(self.privchats[self.chat_message_to].size[0]/2)
         posY = self.position[1]+(self.size[1]/2)-(self.privchats[self.chat_message_to].size[1]/2)
         if posX > 0 and posY > 0:
            self.privchats[self.chat_message_to].position = (posX, posY)
         self.privchats[self.chat_message_to].visible = True

   def on_PrivChatClose(self, userto):
      try:
         del self.privchats[userto]
      except:
         pass
      

   def addToChatWindow(self, who, data, color="blue"):
      #dstr = time.strftime("%d-%b-%y %H:%M:%S", time.localtime())
      dstr = time.strftime("%H:%M:%S", time.localtime())
      html="<child><br /><font color=\"gray\" size=\""+self.chatfontsize+"\">["+dstr+"] </font>"
      handle="&lt;"+who+"&gt;"
      if self.latest==who:
         handle="..."
      self.latest=who
      html+="<font color=\""+color+"\" size=\""+self.chatfontsize+"\"><b>"+handle
      html+=" </b></font><font size=\""+self.chatfontsize+"\">"+data+"</font></child>"
      self.chathtml.append(html)
      self.Freeze()
      if len(self.chathtml) > 500:
         del self.chathtml[0]
         self.components.ChatArea.SetPage("".join(self.chathtml))
      else:
         self.components.ChatArea.AppendToPage(html)
      y = self.components.ChatArea.GetInternalRepresentation().GetHeight()
      self.components.ChatArea.Scroll(0, y)
      self.Thaw()

   def on_incomingChat(self, result):
      color = 'green'
      if str(result[0]) == 'Skylive Server':
            color = 'gray'
      if str(self.username) != str(result[0]):
         self.addToChatWindow(result[0], result[1], color)

      #txt = '<'+result[0]+'> '+result[1]
      #if str(self.username) != str(result[0]):
      #   self.oldtxt = self.components.ChatArea.text.split("\n")
      #   if len(self.oldtxt) < 500:
      #      self.components.ChatArea.appendText(txt+'\n')
      #   else:
      #      #Set remove(0,self.firstLine+1) --> +1 for remove \n char 
      #      self.firstLine = self.components.ChatArea.getLineLength(0)
      #      self.components.ChatArea.remove(0,self.firstLine+1)
      #      self.components.ChatArea.appendText(txt+"\n")

   def on_menuSaveChat_select(self, event):
       #TODO: it's unable to write chat if special char are present in text
       #self.chatPubText = self.components.ChatArea.text.encode('latin-1')
       self.chatPubText = "\n".join(self.chathtml)
       self.chat_file_path = os.path.expanduser("~")
       self.chat_file_usr_path = os.path.normpath(self.chat_file_path+"/skylive-ng_chat")
       result = dialog.saveFileDialog(self, self.getText('savechattext1'), self.chat_file_usr_path, 'chat.txt', 'Text Files: (*.txt)|*.txt')
       if result.accepted:
          self.path = result.paths[0]
          self.chat_file = open(self.path,"w")
          self.chat_file.write(self.getText('savechattext2')+self.chatPubText)
          self.chat_file.close()
          self.alertDialog(self.getText('savechattext3')+self.path)

   def on_menuBooking_select(self, event):
      self.bookingPop = model.childWindow(self, booking.Booking, "./gui/booking.rsrc.py")
      self.bookingPop.visible = True


   def on_menuAccount_select(self, event):
      self.userinfoPop = model.childWindow(self, userinfo.UserInfo, "./gui/userinfo.rsrc.py")
      self.userinfoPop.visible = True


   def addToPrivChatWindow(self, who, data, to, color="blue"):
      #dstr = time.strftime("%d-%b-%y %H:%M:%S", time.localtime())
      dstr = time.strftime("%H:%M:%S", time.localtime())
      html="<child><br /><font color=\"gray\" size=\""+self.chatfontsize+"\">["+dstr+"] </font>"
      handle="&lt;"+who+"&gt;"
      if self.privchats[to].latest==who:
         handle="..."
      self.privchats[to].latest=who
      html+="<font color=\""+color+"\" size=\""+self.chatfontsize+"\"><b>"+handle
      html+=" </b></font><font size=\""+self.chatfontsize+"\">"+data+"</font></child>"
      pchathtml = self.privchats[to].chathtml
      pchathtml.append(html)
      self.Freeze()
      if len(pchathtml) > 500:
         del pchathtml[0]
         self.privchats[to].components.ChatArea.SetPage("".join(pchathtml))
      else:
         self.privchats[to].components.ChatArea.AppendToPage(html)
      y = self.privchats[to].components.ChatArea.GetInternalRepresentation().GetHeight()
      self.privchats[to].components.ChatArea.Scroll(0, y)
      self.Thaw()
      self.privchats[to].chathtml = pchathtml

   def on_incomingPrivChat(self, result):
      # Messages from server are identical to priv messages from users
      if result[0] == 'Server Skylive':
         self.alertDialog(result[1])
      else:
         self.chat_message_tocomp = result[0]
         if result[0][:1] == '@':
            result[0] = result[0][1:]
         else:
            # This is a bad hack. In the skylive protocol, when a 
            # user is a paying user that can control telescopes, 
            # it has a @ in front of he's nickname. When you need to write a
            # privmsg to this user, you need to send the message to the nick
            # complete with also the initial @, but when you receive a message
            # from a user you don't receive the initial @, so, if a user with
            # the initial @ write a message to you and you don't have a query
            # window open yet, you will get he's nick without the @ char, and
            # the user can't read your answer, and the server don't advise you
            # about that.
            # So, to solve this issue, a very bad hack is to try to find the
            # real nickname on the channel list, hoping that the user is
            # already in the same channel. Maybe in future we will do
            # something like modify the server to solve this issue.
            for nick in self.components.UserlistArea.items:
               if nick[1:] == self.chat_message_tocomp:
                  self.chat_message_tocomp = nick

         #txt = '<'+result[0]+'> '+result[1]
         self.chat_message_to = result[0]
         self.on_PrivMesgClick(False)

         color = 'green'
         if str(result[0]) == 'Skylive Server':
            color = 'gray'
         if str(self.username) != str(result[0]):
            self.addToPrivChatWindow(result[0], result[1], result[0], color)

         #self.oldtxt = self.privchats[result[0]].components.ChatArea.text.split("\n")
         #if len(self.oldtxt) < 500:
         #   self.privchats[result[0]].components.ChatArea.appendText(txt+"\n")
         #else:
         #   self.firstLine = self.privchats[result[0]].components.ChatArea.getLineLength(0)
         #   self.privchats[result[0]].components.ChatArea.remove(0,self.firstLine+1)
         #   self.privchats[result[0]].components.ChatArea.appendText(txt+"\n")


   def on_incomingWebLink(self, result):
      link = result[0]
      try:
         webbrowser.open(link)
      except:
         self.alertDialog("Default WebBrowser is not defined")

   def on_incomingBigLive(self, result):
      self.on_LiveDuplicate(result)


   def on_incomingHtmlMessage(self, result):
      sender = result[0]
      code = result[1]
      width = result[2]
      heigth = result[3]

      rsrc = "./gui/resizableinfo.rsrc.py"
      self.aboutPop = model.childWindow(self, info.infoBox, rsrc)
      self.aboutPop.title = "Message from "+str(sender)
      self.aboutPop.size = (int(width), int(heigth))
      self.aboutPop.panel.SetSize(self.aboutPop.size)
      self.aboutPop.components.infobox.visible=False
      self.aboutPop.components.htmlbox.SetPage(code)
      self.aboutPop.components.htmlbox.visible=True
      self.aboutPop.visible = True
      self.aboutPop.on_size(False)


   def on_statusMessageFromServer(self, message):
      self.StatusTextFormat(message[0], message[1], message[2])

   def on_AuthFromServer(self, status):
      #print "AUTHFROMSERVER"
      try:
         if not self.count:
            self.count=1
         else:
            pass
      except:
            self.count=1
      if not status:
         self.config.changeLoginCredentials(self.count)
         self.srvproto.AuthString(config.getUsername(), config.getPassword())
         self.TwistedLoop.serverReconnect()
         self.count+=1
      else:
         self.TelescopeChange(self.telescopesel)




   def on_ChatSend_mouseClick(self, event):
      txt = self.components.ChatField.text
      self.components.ChatField.text = ''
      if len(txt.replace(" ", "")) > 0:
         self.TwistedLoop.sendNetworkData(self.srvproto.chatSendPublic(txt))
         color = 'red'
         data = parser.toHtml(txt)
         self.addToChatWindow(self.username, data, color)

         #txt = "<"+self.username+"> "+txt
         #self.oldtxt = self.components.ChatArea.text.split("\n")
         #if len(self.oldtxt) < 500:
         #   self.components.ChatArea.appendText(txt+'\n')
         #else:
         #   self.firstLine = self.components.ChatArea.getLineLength(0)
         #   self.components.ChatArea.remove(0,self.firstLine+1)
         #   self.components.ChatArea.appendText(txt+"\n")



   def on_ChatField_keyPress(self, event):
      if event.GetKeyCode() == wx.WXK_RETURN:
         self.on_ChatSend_mouseClick(event)
         event.skip()
      else:
         event.skip()

   def on_ChatSend_gainFocus(self, event):
      # Ugly, bad, orrible hack to make
      # the fucking windows work with RETURN keypress.
      if os.name == 'nt':
         if len(self.components.ChatField.text) > 0:
            self.on_ChatSend_mouseClick(False)
      event.skip()
      self.components.ChatField.setFocus()

   def on_LiveCentrePopupClick(self, event):
      self.TwistedLoop.sendNetworkData(self.srvproto.moveCenter(self.CenterLiveString))

   def on_Live640_mouseContextUp(self, event):
      if self.domeisopen:
         abx, aby = event.position
         sizeX, sizeY = self.components.Live640.size
         relX = str(abx-(sizeX/2))
         relY = str(aby-(sizeY/2))
         if relX[:1] != '-':
            relx='+'+relX.zfill(3)
         else:
            relx='-'+relX[1:].zfill(3)
         if relY[:1] != '-':
            rely='+'+relY.zfill(3)
         else:
            rely='-'+relY[1:].zfill(3)
         self.CenterLiveString = relx+rely

         self.popupID1 = wx.NewId()
         self.popupID2 = wx.NewId()
         self.Bind(wx.EVT_MENU, self.on_LiveCentrePopupClick, id=self.popupID1)
         self.Bind(wx.EVT_MENU, self.on_showLiveDSS, id=self.popupID2)
         if self.adminPrivilege:
            self.popupID3 = wx.NewId()
            self.Bind(wx.EVT_MENU, self.on_activateCross, id=self.popupID3)
         if not self.livedup:
            self.popupID4 = wx.NewId()
            self.Bind(wx.EVT_MENU, self.on_LiveDuplicate, id=self.popupID4)
         menu = wx.Menu()
         menu.Append(self.popupID1, self.getText('poplivemenu1'))
         menu.Append(self.popupID2, self.getText('poplivemenu2'))
         if self.adminPrivilege:
            if self.ciceroneMode:
               menu.Append(self.popupID3, self.getText('poplivemenu3'))
            else:
               menu.Append(self.popupID3, self.getText('poplivemenu4'))
         if not self.livedup:
            menu.Append(self.popupID4, self.getText('poplivemenu5'))

         self.popupID5 = wx.NewId()
         self.Bind(wx.EVT_MENU, self.on_autoFocus, id=self.popupID5)
         menu.Append(self.popupID5, 'autofocus')


         if self.adminPrivilege:

            mfstr = 'manual focus'
            if self.focusdialog:
               mfstr = 'close manual focus'
            self.popupID6 = wx.NewId()
            #self.Bind(wx.EVT_MENU, self.on_FocusPlus, id=self.popupID6)
            self.Bind(wx.EVT_MENU, self.on_OpenFocus, id=self.popupID6)
            menu.Append(self.popupID6, mfstr)

            #self.popupID7 = wx.NewId()
            #self.Bind(wx.EVT_MENU, self.on_FocusLess, id=self.popupID7)
            #menu.Append(self.popupID7, 'focus-')

            self.popupID7 = wx.NewId()
            self.Bind(wx.EVT_MENU, self.on_sync, id=self.popupID7)
            menu.Append(self.popupID7, 'sync')


         self.PopupMenu(menu, event.GetPosition())
         menu.Destroy


   def on_OpenFocus(self, event):
      if not self.focusdialog:
         self.focusdialog = True
         self.FocusDialogWin = model.childWindow(self, focus.FocusDialog, "./gui/focus.rsrc.py")
         self.FocusDialogWin._parent = self
      else:
         #try:
         self.FocusDialogWin.close(True)
         #except:
         #   pass

   def on_CloseFocus(self, event=False):
      self.focusdialog = False
      del self.FocusDialogWin

   def on_CloseAskStream(self, event=False):
      self.askStreaming = False

   def on_CloseStream(self, event=False):
      self.Streaming = False

   def on_autoFocus(self, event):
      self.TwistedLoop.sendNetworkData(self.srvproto.sendFocus('Auto'))

   
   def on_FocusPlus(self, event):
      self.TwistedLoop.sendNetworkData(self.srvproto.sendFocus('Plus'))

   def on_FocusLess(self, event):
      self.TwistedLoop.sendNetworkData(self.srvproto.sendFocus('Less'))

   def on_sync(self, event):
      self.TwistedLoop.sendNetworkData(self.srvproto.sendSync())

   def on_LiveDuplicate(self, event):
      if not self.livedup:
         self.livedup=model.childWindow(self, liveduplicate.LiveDuplicate, "./gui/liveduplicate.rsrc.py")
         self.livedup._parent = self
         self.livedup.setLiveImage(self.components.Live640.bitmap)
         orw, orh = self.livedup.size
         self.livedup.size = (orw*2, orh*2)
         self.livedup.on_size(False)


   def on_showLiveDSS(self, event):
      ra = self.components.TelescopeRAText.text
      dec = self.components.TelescopeDECText.text
      fov = self.components.TelescopeFOVText.text
      try:
         y = fov.split("x")[0].replace("'", "").replace('"', '').replace(" ", ".")
         x = fov.split("x")[1].replace("'", "").replace('"', '').replace(" ", ".")
         if (ra != "00:00:0" and ra != "00:00.0") and dec.replace("-", "").replace("+", "") != "00.00":
            #print ra, dec, x, y
            ra = str(ra).replace(":", "%20").replace(".", "%20").replace(" ","")
            dec = str(dec).replace(".", "%20").replace(":", "%20").replace(" ", "")
            self.TwistedLoop.downloadDss(ra, dec, x, y, live=True)
      except:
         pass


   def on_ButtonN_mouseClick(self, event):
      self.TwistedLoop.sendNetworkData(self.srvproto.moveNorth())

   def on_ButtonS_mouseClick(self, event):
      self.TwistedLoop.sendNetworkData(self.srvproto.moveSouth())

   def on_ButtonW_mouseClick(self, event):
      self.TwistedLoop.sendNetworkData(self.srvproto.moveWest())

   def on_ButtonE_mouseClick(self, event):
      self.TwistedLoop.sendNetworkData(self.srvproto.moveEast())

   def on_Sponsor_mouseClick(self, event):
      try:
         webbrowser.open("http://www.skylive.it/test2.htm")
      except:
         self.alertDialog("Default WebBrowser is not defined")

   def on_menuSettingsLogin_select(self, event):
      #print 'MENUSETTINGLOGIN'
      self.config.changeLoginCredentials()
      self.srvproto.AuthString(config.getUsername(), config.getPassword())
      self.TwistedLoop.serverReconnect()
   
   def on_PathChoose_mouseClick(self, event):
      new_PathField = dialog.directoryDialog(self, self.getText('pathchosetext'), self.components.PathField.text)
      if new_PathField.accepted:
         self.components.PathField.text = new_PathField.path
         self.config.put_usrDefaultPath(new_PathField.path)
         self.usrDefSavePath = new_PathField.path
   
   def on_PhotoSendToScript_mouseClick(self, event):
      self.filename_seq = self.components.FileName.text
      sep = self.scriptSep
      if self.photo['bin'] and self.photo['filter'] and self.photo['exp'] and self.photo['repeat'] and self.filename_seq:
         self.fileFounded = False
         self.lastFileNumber = -1
         for files in os.listdir(self.components.PathField.text):
            fileFound = os.path.splitext(files)[0]
            #print 'trovato file: ',fileFound
            fileNameWOnum = fileFound[:-4]
            if fileNameWOnum == self.filename_seq:
               self.fileFounded = True
               number = int(fileFound[-3:])
               if number > self.lastFileNumber:
                  self.lastFileNumber = number
         if self.fileFounded:
            self.startN = str(self.lastFileNumber + 1)
         else:
            self.startN = str(self.photo['startn'])
         
         self.scripts_count = self.scripts_count +1
         self.script_line = "n."+str(self.scripts_count)+sep+"PHOTO"+sep+str(self.photo['exp']).zfill(3)+sep+str(self.photo['filter'])+sep+str(self.photo['guide'])+sep+str(self.photo['aflat'])+sep+str(self.photo['adark'])+sep+str(self.photo['web'])+sep+"BIN"+sep+str(self.photo['bin'])+sep+self.startN.zfill(3)+sep+str(self.photo['repeat'])+sep+os.path.normpath(self.components.PathField.text+"/"+self.filename_seq)
         self.scripts.append(self.script_line)
         self.updateScript()
   
   def on_PointSendToScript_mouseClick(self, event):
      sep = self.scriptSep
      if self.selectedTarget:
         try:
            pointstring = self.srvproto.moveToTarget(self.selectedTarget)
         except:
            pointstring = False

      if pointstring:
         pointstringcmdS = pointstring.split("#^#")
         pointstringscript = pointstringcmdS[3]
         self.scripts_count = self.scripts_count +1
         self.script_line = "n."+str(self.scripts_count)+sep+"GOTO"+sep+pointstringscript
         self.scripts.append(self.script_line)
         self.updateScript()

   def updateScript(self):
      self.components.ScriptArea.Clear()
      if self.scripts:
         for script in self.scripts:
            self.components.ScriptArea.append(script)
      else:
         self.scripts_count=0

   def on_ScriptArea_mouseContextUp(self, event):
      sel = self.components.ScriptArea.GetSelections()
      if len(sel) > 0:
         script_sel = self.components.ScriptArea.getString(sel[0])
         self.script_to_del = script_sel
         relX, relY = event.GetPosition()
         fX, fY = self.components.ScriptArea.position
         self.popupID2 = wx.NewId()
         self.Bind(wx.EVT_MENU, self.on_deleteScript, id=self.popupID2)
         menu = wx.Menu()
         menu.Append(self.popupID2, self.getText('scriptmenu1'))
         self.PopupMenu(menu, (relX+fX, relY+fY))
         menu.Destroy

   def on_deleteScript(self, event):
      self.scripts.remove(self.script_to_del)
      self.updateScript()
      
   def on_ScriptClear_mouseClick(self,event):
      self.components.ScriptArea.Clear()
      self.scripts=[]
      self.scripts_count=0
   
   def on_ScriptSave_mouseClick(self, event):
      sep = self.scriptSep
      if self.scripts:
         self.script_tosave=[]
         for script in self.scripts:
            script_save = script.split(sep)
            self.script_tosave.append(sep.join(script_save[1:]))
         self.ScriptFileTxt = "\n".join(self.script_tosave)
         ScriptSaveFile = dialog.saveFileDialog(self, self.getText('scriptsavetext1'), self.components.PathField.text, 'script.sks', self.getText('scriptsavetext2')+'(*.sks)|*.sks')
         if ScriptSaveFile.accepted:
            self.path = ScriptSaveFile.paths[0]
            self.script_file = open(self.path,"w")
            self.script_file.write(self.ScriptFileTxt)
            self.script_file.close()

   def on_ScriptLoad_mouseClick(self, event):
      ScriptLoadFile = dialog.fileDialog(self, self.getText('scriptloadtext1'), self.components.PathField.text, ' ', self.getText('scriptloadtext2')+'(*.sks)|*.sks')
      sep = self.scriptSep
      if ScriptLoadFile.accepted:
         self.load_path = ScriptLoadFile.paths[0]
         self.script_file = open(self.load_path,"r")
         self.ScriptFileTxt = self.script_file.read()
         if len(self.ScriptFileTxt) > 0:
            self.script_toload = self.ScriptFileTxt.split("\n")
            for script in self.script_toload:
               self.scripts_count = self.scripts_count + 1
               self.scripts.append("n."+str(self.scripts_count)+sep+script)
            self.updateScript()

   def on_ScriptStart_mouseClick(self, event):
      sysType = self.systemType
      if not os.path.exists(os.path.normpath("./gui/scriptsgui."+sysType+".rsrc.py")):
         sysType = "Linux"
      if self.scripts:
         self.scriptgui = model.childWindow(self, scriptsgui.Scriptsgui, "./gui/scriptsgui."+sysType+".rsrc.py")
         self.scriptgui._parent = self
         self.scriptgui.scripts = self.scripts
         self.scriptgui.actualtel = self.telescopesel
         posX = self.position[0]+(self.size[0]/2)-(self.scriptgui.size[0]/2)
         posY = self.position[1]+(self.size[1]/2)-(self.scriptgui.size[1]/2)
         self.scriptgui.position = (posX, posY)
         self.scriptgui.visible = True
         self.scriptguiStarted = True

   def on_photoStatus(self, message):
      if message == "notReady":
         # uploading photo to server
         # XXX i think do nothing ... but i use it to double check before download photo.
         if self.photoKeyClick:
            self.photoInUpload = True
      elif message == "Ready":
         # photo ready to be downloaded
         if self.photoKeyClick and self.photoInUpload:
            self.photoKeyClick = False
            self.photoInUpload = False
            self.TwistedLoop.downloadFits(self.telescopesel)

   def on_downPopOpen(self, size, uniqueid):
      if not uniqueid in self.downPop.keys():
         self.downPop[uniqueid] = model.childWindow(self, downprog.DownProgr, "./gui/downprog.rsrc.py")
         self.downPop[uniqueid].title = self.getText('downloadtitle')+size+" kb"
         self.downPop[uniqueid].components.downpr.text = self.getText('downloadtext')+size+" kb"
         self.downPop[uniqueid].visible = True

   def on_downPopUpdate(self, *args):
      try:
         uniqueid=args[2]
         self.downPop[uniqueid].components.downpr.text = args[0]
         self.downPop[uniqueid].components.progBar.value = int(args[1])
         self.downPop[uniqueid].components.progPerc.text = str(int(args[1]))+'%'
      except:
         pass
      
   def on_downPopClose(self, uniqueid):
      try:
         self.downPop[uniqueid].close()
         del self.downPop[uniqueid]
      except:
         pass

   def on_menuFitsOpen_command(self, event):
      self.FistOpener = model.childWindow(self, fitsopener.FitsOpener, "./gui/fitsopener.rsrc.py")
      self.FistOpener.parent = self
      self.FistOpener.visible = True

   def on_requestData(self, req):
      if req:
         self.srvproto.AuthString(str(config.getUsername()), str(config.getPassword()))
         self.TwistedLoop.sendNetworkData(self.srvproto.MsgLogin())
         if self.initialized and self.connLoose:
            self.connLoose = False
   
   def on_about_skylive_command(self,event):
      rsrc = "./gui/info.rsrc.py"
      if self.systemType == 'Darwin':
	      rsrc = "./gui/info.rsrc.Darwin.py"
      self.aboutPop = model.childWindow(self, info.infoBox, rsrc)
      self.aboutPop.title = self.getText('aboutTitle')
      self.aboutPop.components.infobox.visible=False
      self.aboutPop.components.htmlbox.SetPage("""
      <font size="2">
      Skylive-ng project by:<br>
      <br>
      Copyright (C) 2007-2009 Franco Lanza <nextime@nexlab.it><br>
      Copyright (C) 2007-2009 Sandro Aliano <ita595@hotmail.com><br>
      Copyright (C) 2007-2009 Ivan Bellia <skylive@skylive.it><br>
      <br><br>
      Trac Site : <a href="http://www.astronomix.org/trac/wiki/SkyLiveNG">
      http://www.astronomix.org/trac/wiki/SkyLiveNG</a><br>
      Web Site  : <a href="http://www.skylive.it">http://www.skylive.it</a><br><br>
      <a href="http://www.astronomix.org/trac/wiki/helpClientNG">More Info - Maggiori informazioni</a><br>

      </font>
      """)
      self.aboutPop.components.htmlbox.visible=True
      self.aboutPop.visible = True

   def createFileName(self):
      #Filename structure : objname_selected-filter_bin_exp-time_xxx.fit
      if self.initialized and not self.custom_fn:
         sep = "_"
         fn1 = self.components.CurrentObjectText.text
         charlist = ":-.+"
         for x in charlist:
            fn1= fn1.replace(x ,'') 
         fn2 = self.components.ComboFilters.text
         fn3 = str(self.components.ComboBin.text)
         fn4 = str(self.components.SpinnerExposition.value)
         name = fn1+sep+fn2+sep+fn3+sep+fn4
         self.components.FileName.text=name
      elif not self.initialized and self.custom_fn:
         name = "SkyliveNG"
         self.components.FileName.text=name

   def on_PhotoTXTFilename_mouseClick(self, event):
      self.custom_fn = True
      result = dialog.textEntryDialog(self,
                                    self.getText('filenameDialog1'),
                                    self.getText('filenameDialog2'),
                                    self.components.FileName.text)
      if result.accepted:
         self.components.FileName.text = result.text
      else:
         self.custom_fn = False
         self.createFileName()
         
   def on_telescopeFeat(self, args):
      arg = args.split("**")
      self.components.TelescopeModelText.text=str(arg[0])
      self.components.TelescopeFocalText.text=str(arg[4])
      self.components.TelescopeFOVText.text=str(arg[3])
      self.components.TelescopeCCDText.text=str(arg[1])
      self.components.TelescopeFiltersText.text=str(arg[2])
      self.changeFilters(arg[2])

      
   def on_domeStatus(self, arg):
      if arg.lower() != "closed":
         self.domeisopen = True
         if arg.lower() == 'unknown':
            self.components.ObservatoryDomeText.text = self.getText('unknown')
         else:
            self.components.ObservatoryDomeText.text= self.getText('domeopen')
      else:
         self.domeisopen = False
         self.components.ObservatoryDomeText.text= self.getText('domeclosed')
   
   def on_rainStatus(self, arg):
      stat = arg.lower()
      if stat == 'clear' or stat == 'clean':
         ret = self.getText('weatherclean')
      elif stat == 'cloudy':
         ret = self.getText('weathercloudy')
      elif stat == 'vcloudy':
         ret = self.getText('weathervcloudy')
      elif stat == 'rain':
         ret = self.getText('weatherrain')
      else:
         ret = self.getText('unknown')
      self.components.RainSensorText.text= ret
   
   def on_objName(self, arg):
      self.components.CurrentObjectText.text=str(arg)
      self.createFileName()
      
   #def on_PingReq(self, arg):
   #   # XXX We shuld answer directly from the twisted part!
   #   if arg:
   #      self.TwistedLoop.sendNetworkData(self.srvproto.sendPong())
   
   def on_LonLat(self, args):
      arg = args.split("**")
      self.components.TelescopeGPSPos2.text = str(arg[0])
      self.components.TelescopeGPSPos1.text = str(arg[1])

   def on_dssGifDownloaded(self, gif, live=False):
      sysType = self.systemType
      if not os.path.exists(os.path.normpath("./gui/imager."+sysType+".rsrc.py")):
         sysType = "Linux"
      self.DssImager = model.childWindow(self, imager.SkyliveImager, "./gui/imager."+sysType+".rsrc.py")
      self.DssImager._parent = self
      posX = self.position[0]+(self.size[0]/2)-(self.DssImager.size[0]/2)
      posY = self.position[1]+(self.size[1]/2)-(self.DssImager.size[1]/2)
      self.DssImager.position = (posX, posY)
      self.DssImager.title = self.getText('dssTitle')
      im = Image.open(gif)
      if not live:
         try:
            dssgif = im.resize((self.xsizeBit,self.ysizeBit))
         except:
            xsize, ysize = im.size
            self.xsizeBit = xsize/4 
            self.ysizeBit = ysize/4 
            dssgif = im.resize((self.xsizeBit,self.ysizeBit))
      else:
         xsize, ysize = im.size
         self.xsizeBit = xsize/4
         self.ysizeBit = ysize/4
         dssgif = im.resize((self.xsizeBit,self.ysizeBit))

      image = wx.EmptyImage(self.xsizeBit, self.ysizeBit)
      image.SetData(dssgif.convert("RGB").tostring())
      newBitmap = graphic.Bitmap()
      newBitmap.setImageBits(image)
      self.DssImager.components.ImageShow.bitmap = newBitmap
      self.DssImager.size = (self.xsizeBit+20, self.ysizeBit+100)
      oxc, oyc = self.DssImager.components.ButtonClose.position
      self.DssImager.components.ButtonClose.position = (oxc, oyc-240+int(self.ysizeBit))
      self.DssImager.components.ButtonClose.visible = True
      self.DssImager.fromEvent = "dssGif"
      self.DssImager.visible = True
      
   def on_setStars(self, list):
      if not self.starsSetted:
         p = protocol.ProtoParser()
         res = list.split(";")
         self.starlist = p.ParseLX200CatalogFromSkylive(res)
         self.setStarsList()
         self.starsSetted = True

   def on_setFWHM(self, fwhm):
      self.components.FWHMText.text = str(fwhm)

   def on_Streaming(self,  suri):
      oldStream = self.StreamUri
      self.StreamUri = suri
      if self.StreamUri == 'NONE':
         if self.Streaming:
            try:
               self.Streaming.close()
            except:
               pass
      else:
         if not self.Streaming:
            self.on_menuVideoOpen_command()
         else:
            if oldStream != self.StreamUri:
               self.Streaming.close()
               self.on_menuVideoOpen_command()

   def on_ForceStreaming(self, suri):
      oldStream = self.StreamUri
      self.StreamUri = suri
      if self.StreamUri == 'NONE':
         if self.Streaming:
            try:
               self.Streaming.close()
            except:
               pass
      else:
         if not self.Streaming:
            self.on_menuVideoOpen_command(force=True)
         else:
            if oldStream != self.StreamUri:
               self.Streaming.close()
               self.on_menuVideoOpen_command(force=True)


   def on_setDoubles(self, list):
      if not self.doubleSetted:
         p = protocol.ProtoParser()
         res = list.split(";")
         self.doublelist = p.ParseLX200CatalogFromSkylive(res)
         self.setDoublesList()
         self.doubleSetted = True
   
   def on_setTscopeCombo(self, tnum):
      if not self.TscopeComboSetted:
         for tscope in range(1, int(tnum)+1):
            self.components.TScopeCombo.append(self.getText('TScopeComboGen') % str(tscope))
         self.TscopeComboSetted = True
   
   def on_setAdminPriv(self, isAdmin):
      if isAdmin:
         self.adminPrivilege = True

   def resetCiceroneMode(self):
      self.ciceroneMode = False
      self.resendCrossC = False
      self.addCross = False
      sizeX, sizeY = self.components.Live640.size
      self.ciceronePosx = sizeX/2
      self.ciceronePosy = sizeY/2
   
   def on_activeCicerone(self, posxy):
      self.addCross = True
      self.ciceronePosx = posxy[0]
      self.ciceronePosy = posxy[1]
   
   def drawCross(self, liveImage, pox, poy):
      posx = int(pox)
      posy = int(poy)
      p = ImageFile.Parser()
      p.feed(liveImage)
      im = p.close()
      draw = ImageDraw.Draw(im)
      draw.line([(posx, posy),(posx+15, posy+15)], fill=self.defaultPointerColor, width=1)
      draw.line([(posx, posy),(posx+7, posy)], fill=self.defaultPointerColor, width=1)
      draw.line([(posx, posy),(posx, posy+10)], fill=self.defaultPointerColor, width=1)
      del draw 
      image = wx.EmptyImage(320, 240)
      image.SetData(im.convert("RGB").tostring())
      Bitmap = graphic.Bitmap()
      Bitmap.setImageBits(image)
      try:
         self.components.Live640.bitmap = Bitmap
         self.liveBitmap = Bitmap
         self.addCross = False
      except:
         pass

   def on_Live640_mouseDoubleClick(self, event):
      if self.adminPrivilege and self.ciceroneMode:
         abx, aby = event.position
         self.crossX = abx
         self.crossY = aby
         command = self.srvproto.sendCross(str(abx), str(aby))
         self.TwistedLoop.sendNetworkData(command)
         self.resendCrossC = True
   
   def resendCross(self):
      command = self.srvproto.sendCross(str(self.crossX), str(self.crossY))
      self.TwistedLoop.sendNetworkData(command)

   def on_activateCross(self, event):
      if self.ciceroneMode:
         self.ciceroneMode = False
      else:
         self.ciceroneMode = True

   def writeARDEC(self, ra, dec):
      #this is to fit old fake driver for windows skymap to track scope position
      if self.systemType == "Windows" and self.useExtProgram == 'True':
         txt = ra+'#'+dec.replace('*','.')+'#'
         # XXX It is better to choose a TEMP path
         # but we have also to modify the fake driver
         ardecFile = open('c:\\ardec.txt',"w")
         ardecFile.write(txt)
         ardecFile.close()

   def on_menuSettingsPreference_select(self, event):
      self.usrSettings = model.childWindow(self, settings.Settings, "./gui/settings/settings.rsrc.py")
      self.usrSettings._parent = self
      self.usrSettings.visible = True
   
   def setCharSizes(self):
      if self.charSizes:
         self.chatfontsize = self.charSizes['chatsize']
         #self.components.ChatArea.font = {'size':int(self.charSizes['chatsize'])}
         self.components.UserlistArea.font = {'size':int(self.charSizes['listsize'])}
         self.components.ChatField.font = {'size': int(self.charSizes['inputsize'])}
   
   def on_OnLineHelp_command(self, event):
      try:
         webbrowser.open("http://www.astronomix.org/trac/wiki/helpClientNG")
      except:
         self.alertDialog("Default WebBrowser is not defined")
   
   def on_menuMeteoOpen_command(self, event):
      try:
         webbrowser.open("http://www.astronomix.org/trac/wiki/meteoClientNG")
      except:
         self.alertDialog("Default WebBrowser is not defined")
   
   def on_menuVideoOpen_command(self, event=False, force=False):
      self.enableStream, self.askStream=config.get_streamingPref()
      if not self.askStreaming and not self.Streaming and self.askStream in ['True', 'yes', 'y', 'Yes', '1']:
         self.askStreaming = model.childWindow(self, askstream.AskStream, "./gui/askstream.rsrc.py")
      elif not self.askStreaming and not self.Streaming and self.enableStream in ['True', 'yes', 'y', 'Yes', '1']:
         self.on_realStartStream(event)
      elif not self.askStreaming and not self.Streaming and force:
         # We are configure to not ask, but we have no streaming enabled, so, we ask
         # anyway.
         self.askStreaming = model.childWindow(self, askstream.AskStream, "./gui/askstream.rsrc.py")

   def on_realNoStream(self, event):
      if self.askStreaming:
         # Called from the askStreaming window
         if self.askStreaming.components.save.checked:
            config.put_streamingPref(False, False)
         self.askStreaming.close(True)

   def on_realStartStream(self, event):
      if self.askStreaming:
         if self.askStreaming.components.save.checked:
            config.put_streamingPref(True, False)
         self.askStreaming.close(True)
      if not self.Streaming:
         self.Streaming = model.childWindow(self, stream.Stream, "./gui/stream.rsrc.py")


   def getText(self, item):
      return self.ItemText(self.lang, self.gui, item)
   
   def setGui(self):
      self.components.Pointing.label = self.getText('Pointing')
      self.components.PhotoInputs.label = self.getText('PhotoInputs')
      self.components.CCDBox.label = self.getText('CCDBox')
      self.components.StatusBox.label = self.getText('StatusBox')
      self.components.StaticBox4.label = self.getText('StaticBox4')
      self.components.Telescope.label = self.getText('Telescope')
      self.components.TScopeCombo.text = self.getText('TScopeCombo')
      self.components.ChatSend.label = self.getText('ChatSend')
      self.components.ButtonN.label = self.getText('ButtonN')
      self.components.ButtonW.label = self.getText('ButtonW')
      self.components.ButtonE.label = self.getText('ButtonE')
      self.components.ButtonS.label = self.getText('ButtonS')
      self.components.ComboPlanets.text = self.getText('ComboPlanets')
      self.components.PointPlanets.text = self.getText('PointPlanets')
      self.components.ComboStars.text = self.getText('ComboStars')
      self.components.PointStars.text = self.getText('PointStars')
      self.components.ComboDouble.text = self.getText('ComboDouble')
      self.components.PointDouble.text = self.getText('PointDouble')
      self.components.ComboMessier.text = self.getText('ComboMessier')
      self.components.PointMessier.text = self.getText('PointMessier')
      #self.components.ComboIC.text = self.getText('ComboIC')
      self.components.PointAR1.text = self.getText('PointAR1')
      self.components.PointGOTO.label = self.getText('PointGOTO')
      self.components.PointSendToScript.label = self.getText('PointSendToScript')
      self.components.PathChoose.label = self.getText('PathChoose')
      self.components.LastPhoto.label = self.getText('LastPhoto')
      self.components.BigLive.label = self.getText('BigLive')
      self.components.MakePhoto.label = self.getText('MakePhoto')
      self.components.PhotoSendToScript.label = self.getText('PhotoSendToScript')
      self.components.PhotoTXTRepeat.text = self.getText('PhotoTXTRepeat')
      self.components.PhotoTXTStartnumber.text = self.getText('PhotoTXTStartnumber')
      self.components.PhotoTXTFilename.label = self.getText('PhotoTXTFilename')
      self.components.PhotoTXTGuide.text = self.getText('PhotoTXTGuide')
      self.components.PhotoTXTFilter.text = self.getText('PhotoTXTFilter')
      self.components.PhotoTXTExp.text = self.getText('PhotoTXTExp')
      self.components.ScriptLoad.label = self.getText('ScriptLoad')
      self.components.ScriptSave.label = self.getText('ScriptSave')
      self.components.ScriptStart.label = self.getText('ScriptStart')
      self.components.ScriptStop.label = self.getText('ScriptStop')
      self.components.ScriptContinue.label = self.getText('ScriptContinue')
      self.components.ScriptClear.label = self.getText('ScriptClear')
      self.components.ScriptReset.label = self.getText('ScriptReset')
      self.components.ScriptStatus.text = self.getText('ScriptStatus')
      self.components.StatusRain.text = self.getText('StatusRain')
      self.components.StatusDome.text = self.getText('StatusDome')
      self.components.StatusObject.text = self.getText('StatusObject')
      self.components.TelescopeCCDTemp.text = self.getText('TelescopeCCDTemp')
      self.components.MoveRA.text = self.getText('MoveRA')
      self.components.TelescopeFilters.text = self.getText('TelescopeFilters')
      self.components.TelescopeGPS.text = self.getText('TelescopeGPS')
      self.components.TelescopeGPS2.text = self.getText('TelescopeGPS2')
      self.components.TelescopeFOW.text = self.getText('TelescopeFOW')
      self.components.TelescopeFocal.text = self.getText('TelescopeFocal')
      self.components.TelescopeMODEL.text = self.getText('TelescopeMODEL')
      self.components.Sponsor.label = self.getText('Sponsor')
      submenu = ['menuCheckVersion', 'menuSaveChat', 'menuFileExit', 
                 'menuSettingsLogin', 'menuSettingsPreference',  
                 'menuFitsOpen', 'menuMeteoOpen', 'menuHelpAboutSkyliveNG', 
                 'menuHelpHelpOnLine']
      try:
         for item in submenu:
            idmenuItem = self.menuBar.getMenuId(item)
            self.MenuBar.SetLabel(idmenuItem, self.getText(item))
      except:
         pass
   
   def on_TeleLink(self, stat):
      if stat == 'TeleON':
         self.teleOn = True
      elif stat == 'TeleOFF':
         self.teleOn = False
   
   def on_udpcmd(self, cmd):
      #print "ricevuto ", cmd
      self.on_SelectTarget('AR', cmd)
      #print self.selectedTarget
      try:
         pointstring = self.srvproto.moveToTarget(self.selectedTarget)
      except:
         pointstring = False

      if pointstring:
         self.TwistedLoop.sendNetworkData(pointstring)
   
   def on_indicmd(self, cmd):
      # XXX for the moment just like udpcmd
      #print 'INDI COMMAND', cmd
      self.on_udpcmd(cmd)

   def writeARDECIndi(self, RA, DEC):
      ra = RA.replace('.', ':')
      dec = DEC.replace('.', ':')
      self.TwistedLoop.sendINDITelePos(ra, dec)
   
   #def on_ChatArea_mouseDoubleClick(self, event):
   #   x = ''
   #   y = ''
   #   url = False
   #   posA = 0
   #   posB = 0
   #   noUrl = False
   #   cpoint = self.components.ChatArea.getSelection()
   #   while 'http' not in x and '>' not in x:
   #      x = self.components.ChatArea.getString(cpoint[0]-posA, cpoint[0]-posA+4)
   #      if '>' in x or '<' in x:
   #         noUrl = True
   #      posA+=1
   #   if not noUrl:
   #      while y != ' ' and y != '\n':
   #         y = self.components.ChatArea.getString(cpoint[1]+posB, cpoint[1]+posB+1)
   #         posB+=1
   #      A = cpoint[0]-posA+1
   #      B = cpoint[1]+posB-1
   #      text = self.components.ChatArea.getString(A, B)
   #      if len(text.split(' ')) > 1:
   #         urlTry = text.split(' ')[0]
   #      else:
   #         urlTry = text
   #      if len(urlTry) > 12:
   #         url = urlTry
   #   try:
   #      if url:
   #         webbrowser.open(url)
   #   except:
   #      self.dialog.alertdialog(self, "Default WebBrowser is not defined")

   def osxUpgradeDownloaded(self):
      self.dialog.alertdialog(self, self.getText('osxUpgradeDone'))
      self.on_close(self, True)

   def on_ChatArea_mouseDown(self, event):
      self.canSelect = True
      event.skip()

   def on_ChatArea_mouseUp(self, event):
      self.canSelect = False
      event.skip()

   def on_ChatArea_gainFocus(self, event):
      # Ugly, bad, orrible hack to make
      # the fucking windows work with RETURN keypress.
      if not self.canSelect:
         if os.name == 'nt':
            if len(self.components.ChatField.text) > 0:
               self.on_ChatSend_mouseClick(False)
         self.components.ChatField.setFocus()
         event.skip()
   
   def on_ChatArea_keyPress(self, event):
      key = event.GetKeyCode()
      if key in range (31, 128):
         self.components.ChatField.setFocus()
         self.components.ChatField.appendText(unicode(chr(key)))
      else:
         self.components.ChatField.setFocus()
      event.skip()

   def on_setBins(self, bins):
      binitems = bins.split(',')
      self.components.ComboBin.items = []
      self.components.ComboBin.items = binitems
      self.components.ComboBin.text = u'X'

   def script_Command(self, cmd, *args, **kwargs):
      #print 'script command', cmd, args, kwargs
      if self.scriptguiStarted:
         #print 'started'
         try:
            f = getattr(self.scriptgui, cmd)
            if f and callable(f):
               return f(*args, **kwargs)
         except:
            pass

