"""
     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 Pycard.twistedsupport.twistedThreadModel import TwistedThreadApplication
import conn, config #, audio
import fakedriver, indidriver
from twisted.internet import reactor
import time
import protocol
from utils import genutils as utils
import subprocess
import sys, os

class skyLive(TwistedThreadApplication):

   skyClient = False
   tsdiff = 0


   def __init__(self, *args, **kwargs):
      TwistedThreadApplication.__init__(self, *args, **kwargs)
      self.HTTPDownloader = conn.HTTPDownloader(self, 5)
      #self.AudioStream = audio.AudioStream()
      #self.AudioStream.play("http://skylive3.astronomix.org:8000/skylive.ogg")
      #self.AudioStream.play("http://giss.tv:8000/pablito.ogg")
      self.srvproto = protocol.ServerComm(self)
      self.srvproto.AuthString(str(config.getUsername()), str(config.getPassword()))

   def on_skyClientCommand(self, cmd, *args, **kwargs):
      try:
         f = getattr(self, cmd)
      except:
         f = False
      if f and callable(f):
         return f(*args, **kwargs)
      else:
         self.callInGui('on_'+cmd, *args, **kwargs)

   def on_scriptCommand(self, cmd, *args, **kwargs):
      try:
         f = getattr(self, cmd)
      except:
         f = False
      if f and callable(f):
         return f(*args, **kwargs)
      else:
         self.callInGui('script_Command', 'on_'+cmd, *args, **kwargs)        


   def setTelescopeLiveUri(self, *args, **kwargs):
      urilist = args[0][0]
      interval = args[0][1]
      try:
         self.HTTPDownloader.setLiveUri(urilist)
         self.HTTPDownloader.setTiming(int(interval))
         self.HTTPDownloader.wakeUp()
      except:
         pass

   def imgDownloader(self, cmd='start'):
      if cmd in ['start', 'stop']:
         if cmd == 'start':
            self.HTTPDownloader.keepRunning = True
            self.HTTPDownloader.run()
         else:
            self.HTTPDownloader.keepRunning = False

   def checkUpgrade(self, loop=True):
      try:
         self.HTTPDownloader.checkVersion(loop)
      except:
         pass

   def stopCheckUpgrade(self):
      try:
         self.HTTPDownloader.checkUpdate = False
      except:
         pass

   def PingReq(self, tsserver):
      #print 'PING', tsserver
      now = int(time.time())
      self.tsdiff = now-int(tsserver)
      try:
         self.HTTPDownloader.setTSDiff(self.tsdiff)
      except:
         pass
      self.sendNetworkData(self.srvproto.sendPong())

   def changeTelescope(self, tscope):
      self.HTTPDownloader.tscope=tscope
      #self.HTTPDownloader.wakeUp()

   def getLastPhoto(self):
      self.HTTPDownloader.getLastPhoto()

   def downloadFits(self, telescope):
      self.HTTPDownloader.getFitsFile(telescope)

   def downloadUpgrade(self, upuri, nvermd5):
      self.HTTPDownloader.getUpgrade(upuri, nvermd5)

   def upgradeDownloadFailed(self):
      self.callInGui('upgradeDownloadFailed')

   def upgradeDownloadOk(self, installer):
      plat = utils.platform()
      if plat == 'Windows':
         mydir = os.path.normpath(os.path.abspath(os.path.dirname(sys.executable)))
         subprocess.Popen(installer+" /SP- /SILENT /SUPPRESSMSGBOXES /DIR=\""+mydir+"\"")
      elif plat == 'Linux':
         subprocess.Popen("sh "+installer+" UPGRADE", shell=True, preexec_fn = os.setsid)
         self.callInGui('on_StopClient')
      elif plat == 'Darwin':
         hdu = subprocess.Popen("hdiutil attach "+installer, shell=True, stdout=subprocess.PIPE)
         out = hdu.communicate()[0]
         lines = out.split("\n")
         imagepath = False
         for line in lines:
            if len(line.split()) >= 3 and len(line.split()[2]) > 9 and line.split()[2][:9] == '/Volumes/':
               imagepath  = line.split()[2].replace("\n", "")
         if imagepath:
            try:
               tmpfile = os.tempnam()+".sh"
               f = open(imagepath+"/UPGRADE.sh", "r")
               c = f.read()
               f.close()
               f = open(tmpfile, "w")
               f.write(c)
               f.close()
               subprocess.Popen("sh "+tmpfile+" "+imagepath, shell=True, preexec_fn = os.setsid)
               #subprocess.Popen("cp "+imagepath+"/UPGRADE.sh /tmp/", shell=True, stdout=subprocess.PIPE)
               #subprocess.Popen("sh /tmp/UPGRADE.sh "+imagepath, shell=True, preexec_fn = os.setsid)
               self.callInGui('on_StopClient')
            except:
               print 'UPGRADE FAILED'
               self.callInGui('upgradeDownloadFailed')
            #sascript = 'exec osascript <<\EOF\ndo shell script "sh '+tmpfile+'" with administrator privileges'
            #sascript +="\nEOF\nrm -f "+tmpfile+" "+tmpfile2
            #sascript +="\nhdiutil detach "+imagepath+"\nrm -f "+installer
            #sascript +="\nmydir+"/Contents/MacOS/skylive-ng

         else:
            self.callInGui('upgradeDownloadFailed')
      else:
         print 'I CAN\'T UPGRADE, SORRY.'


   def downloadDss(self, ra, dec, x, y, live=False):
      self.HTTPDownloader.getDssFile(ra, dec, x, y, live)

   def serverConnect(self, addr, timeout=0):
      self.skyProxyServer =  conn.ConnectProxy()
      self.proxyData = config.get_usrProxy()
      if str(self.proxyData['useProxy']).lower() in ['si', 'yes', 'true', True, 1]:
         try:
            self.skyProxyServer.startServer()
            if int(timeout) < 3:
               timeout=1
         except:
            pass
      if self.skyClient:
         self.skyClient.stop()
      self.skyClient = conn.skyClient(self, addr)
      if timeout == 0:
         self.skyClient.run()
      else:
         reactor.callLater(timeout, self.skyClient.run)

   def serverDisconnect(self):
      try:
         self.skyProxyServer.stopServer()
      except:
         pass
      print 'Disconnect called'
      try:
         self.skyClient.stop()
      except:
         pass
      self.skyClient = False

   def forcedExit(self):
      self.ExitLoop()

   def serverReconnect(self):
      print 'Reconnect called'
      self.skyClient.reconnect()

   def sendNetworkData(self, data):
      self.skyClient.transportPut(data)

   def scriptGetFitFile(self, tscope):
      self.HTTPDownloader.getFitsScript(tscope)

   def startFakeDriver(self):
      print 'Starting SkyMap Fakedriver'
      if not hasattr(self, 'faked'):
         self.faked = fakedriver.FakeDriver(self)
      if not hasattr(self, 'fakedstarted'):
         self.fakedstarted = False
      if not self.fakedstarted:
         self.faked.startDriver()

   def stopFakeDriver(self):
      print 'Stopping SkyMap Fakedriver'
      if hasattr(self, 'faked'):
         if self.fakedstarted:
            self.faked.stopDriver()

   def fakeDriverMessage(self, msg):
      #self.WxLoop.on_udpcmd(msg)
      self.callInGui('on_udpcmd', msg)

   def startINDIDriver(self):
      print 'Starting INDI support'
      if not hasattr(self, 'indi'):
         self.indi = indidriver.IndiDriver(self)
      if not hasattr(self, 'indistarted'):
         self.indistarted = False
      if not self.indistarted:
         self.indi.startDriver()

   def stopINDIDriver(self):
      print 'Stopping INDI support'
      if hasattr(self, 'indi'):
         if self.indistarted:
            self.indi.stopDriver()

   def sendINDITelePos(self, ra, dec):
      if hasattr(self, 'indi'):
         if self.indistarted:
            self.indi.setTelePos(ra, dec)

   def indiDriverMessage(self, msg):
      #self.WxLoop.on_indicmd(msg)
      self.callInGui('on_indicmd', msg)


   def notifyGuiReconnect(self):
      self.callInGui('on_LoseConnection', True)

   def notifyGuiDisconnect(self):
      try:
         self.callInGui('on_LoseConnection', False)
      except:
         pass
