# -*- coding: utf-8 -*-
from twisted.web import resource, static
import cgi, logging
from nevow import inevow, rend, tags, loaders, flat, athena, stan
import os, sys
import formal
from formal import iformal
from webgui import GenericFormalResponsePage, Translator
from utils import validators, mail, pwgen
from zope.interface import implements
from twisted.internet import defer
from Database import utils as dbutils
import base64, pickle
import time

log = logging.getLogger("Webgui")
curdir=os.path.abspath(os.path.dirname(sys.argv[0]))
template_path = curdir+'/Web/html/Users/'


def uni(s):
   if isinstance(s, str):
      #return s.decode('utf-8', "replace")
      return s.decode('latin-1', "replace")
   elif isinstance(s, unicode):
      #return s.encode('utf-8', "replace")
      return s.encode('latin-1', "replace")
   else:
      return s

class SkyClient(athena.LiveElement):
   jsClass = u'SkyClient.Server'
   docFactory = loaders.stan(
         tags.div(render=tags.directive("liveElement")) #[
         #   tags.script(type="text/javascript", src="/js/loader.js"),
         #]
      )

   # XXX Temporaneo per compatibilita' con il vecchio client
   clientversion = '300'
   osversion = 'Web Client'
   tnum = "1"

   def __init__(self, avatarId=None, *a, **kw):
      super(SkyClient, self).__init__(*a, **kw)
      self.avatarId = avatarId
      self.username = avatarId
      self.uid = time.time()

   @athena.expose
   def sendChat(self, data, dest=False):
      try:
         log.debug(u'sendChat called with data '+uni(data)+u' from user '+uni(self.username))
      except:
         pass
      #self.callRemote('addNewElement', u'antani')
      if not dest:
         dest = self.tnum
      if dest[0] in ['>', '!', '@']:
         dest = dest[1:]
      self.command('sendChat', uni(dest), uni(data), self.username)
      return data

   @athena.expose
   def getUsername(self):
      log.debug(self.username+" Request getUsername")
      return unicode(self.username)

   @athena.expose
   def getUserList(self):
      # XXX Bisogna dividerla per telescopio!
      self.on_sendUserList(self.command('getUserList', self.tnum, self.username))
      return True
 
   @athena.expose
   def exitClient(self, telescope='all', presence=False):
      if telescope == 'all':
         self.disconn(telescope, presence)
      # XXX Gestire la disconnesione da singoli tele


   @athena.expose
   def getPermissions(self):
      return self.perms

   def on_sendChatMessage(self, *args):
      if args[1] != self.username:
         self.callRemote('on_chatMessage', uni(args[0]), uni(args[1]))


   def on_sendUserList(self, ulist):
      try:
         if len(ulist) > 0:
            self.callRemote('on_updateUserList', map(uni, ulist))
      except:
         pass

   def on_sendPrivMessage(self, msg, sender):
      try:
         self.callRemote('on_privMessage', uni(msg) ,uni(sender))
      except:
         pass



class Caller(object):

   def __init__(self, skobj):
      self.skylive = skobj
      self.missing_method_name = None # Hack!

   def __getattribute__(self, name):
      sk = object.__getattribute__(self, 'skylive')
      try:
         return object.__getattribute__(sk, name)
      except:
         self.missing_method_name = name
         log.debug("Missing  Method: "+str(name))
         return object.__getattribute__(self, '__methodmissing__')

   def __methodmissing__(self, *args, **kwargs):
      log.debug("Missing Client method %s called (args = %s) and (kwargs = %s)" % (object.__getattribute__(self, 'missing_method_name'), str(args), str(kwargs)))



class Page(athena.LivePage):
   addSlash = True
   logged = False
   childvars = {}
   docFactory = loaders.stan(
            tags.html[
               tags.head(title="SkyliveX", render=tags.directive("liveglue"))[
                  #tags.script(type="text/javascript", src="http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js"),
                  tags.script(type="text/javascript", src="/js/QxSettings.js"),
                  tags.script(type="text/javascript", src="/qx/script/qx-release.js"),
                  #tags.script(type="text/javascript", src="/qx/script/qx-loader.js"),
                  #tags.link(rel="stylesheet", type="text/css", href="/resources/css/ext-all.css"),
                  #tags.script(type="text/javascript", src="/script/qxInline.js"),
                  #tags.script(type="text/javascript", src="/script/ext-base.js"),
                  #tags.script(type="text/ipt", src="/script/ext-all.js"),
                  #tags.script(type="text/javascript", src="/script/pwt.js")
               ],
               tags.body[
                  tags.div(render=tags.directive("skyclient")),
                  tags.h3[
                     tags.span["Benvenuto "],
                  ],
               ],
            ])


   def __init__(self, avatarId=None):
      super(Page, self).__init__(self)
      self.avatarId = avatarId
      self.username = avatarId
      self.jsModules.mapping[u'SkyliveGui'] = curdir+'/Web/js/skyliveX.js'
      self.jsModules.mapping[u'SkyClient'] = curdir+'/Web/js/SkyClient.js'
      #self.jsModules.mapping[u'QooXdoo' ] = curdir+'/Web/qx/script/qx-release.js'
      self.jsModules.mapping[u'QxLoader' ] = curdir+'/Web/js/QxLoader.js'


   def beforeRender(self, ctx):
      d = self.notifyOnDisconnect()
      d.addErrback(self.disconn)

   def disconn(self, reason=None, telescope='all', presence=False):
      # XXX Gestire da cosa esce. Non solo i telescopi,
      # ma anche la presenza nel nuovo client.
      self.command('exitTelescope', '1', user=self.username)


   def render_skyclient(self, context, data):
      f = SkyClient(self.avatarId)
      f.command = self.command 
      f.disconn = self.disconn
      f.perms = self.perms
      f.setFragmentParent(self)

      # XXX Temporaneo
      self.command('setUserConnection', Caller(f), user=self.avatarId)
      self.command('EnterTelescope', '1', user=self.avatarId)

      return context.tag[f]


