# Copyright (C) 2009 Daniel Carvalho <idnael@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __pyjamas__ import JS


# Converts javascript structures from googlemaps javascript library to
# python structures, and vice-versa.
#
# Example:
# jsobj=JS("""[{nome:"danire", year:1814}, {nome:"joano", year:"1901"}]""")
#
# #print jsobj[0].nome  # this is an error!
#
# fields = dictToJs({"lista": 'l', "lista[]": 'd'})
# pyobj=translateGmapsObject(jsobj,"lista",fields)
# for line in pyobj:
#   print line.nome, line.year
#
# jsobj2=translateGmapsObject(pyobj,"lista",fields,True)
# #jsobj2 is exactly the same as jsobj!


def translateGmapsObject(obj, fieldName, fields, pyToJs):
    JS("""
    //console.log("translateGmapsObject " + fieldName+"("+pyToJs+")")

    if (! (fieldName in fields))
    {
      //console.log("nothing")
      return obj;
    }
    else{
        action = fields[fieldName]
        //console.log("action=" + action)

        if (action == 'd')
        {
          //console.log("is dict")
          // this newobj can be used in js and also in python, 
          // like this "newobj.field"
          var newobj = {}
          for (var i in obj)
             // vai ficar disponivel como uma propriedade, no python!
             newobj[i] = Utils.translateGmapsObject(obj[i], i, fields, pyToJs);
          return newobj

        }
        else if (action == 'l')
        {
          if (pyToJs) {
              var newobj = Utils.listToJs(obj)
              //console.log("is list py->js")
              for (var i in newobj){
                 newobj[i]=Utils.translateGmapsObject(
                    newobj[i], fieldName + "[]", fields,pyToJs ) ;
              }
              return newobj
          }else{
              //console.log("is list js->py")
              var newobj = pyjslib.list([])
              for (var i in obj)
                 newobj.append(Utils.translateGmapsObject(
                     obj[i], fieldName + "[]", fields,pyToJs ));
              return newobj
          }
        }
        else
        {
          //console.log("is special")
          return action(obj)
        }
    }
    """)


# converts a python dict to js
# It can be used in python functions that have variable number of args
#
# like
# def MapOptions(**params):
#     return dictToJs(params)
#
# if MapOptions is called without arguments, the for loop will
# raise an exception.
# I could use the test "if params" BUT it always gives True...
# So I have to catch the exception.


def dictToJs(dict):
    obj = JS("{}")
    try:
        for key in dict:
            value = dict[key]
            JS("obj[key] = value")
    except:
        pass

    return obj


# Converts a python list to a javascript list
def listToJs(list):
    obj = JS("[]")
    for i in list:
        obj.push(i)
    return obj


# LISTENERS

# This functions add python listener methods to any
# gmaps javascript object


def createListenerMethods(obj):
    obj.addListener = __addListener
    obj.removeListener = __removeListener
    obj.clearListeners = __clearListeners
    obj.clearInstanceListeners = __clearInstanceListeners

    #obj.dumpListeners = __dumpListeners # para debug

    obj.__listeners = {} #__ !


def __dumpListeners():
    self = JS("this")
    print "DUMP"
    for eventName in self.__listeners:
        print "  " + eventName
        for list in self.__listeners[eventName]:
            print "    " + str(list)


def __addListener(eventName, callback):
    self = JS("this")

    list = JS("""
       $wnd.google.maps.event.addListener(this, eventName, function(event) {
         callback(event);
       });
    """)

    # I have to keep information about the registered listeners for
    # this instance!

    if eventName in self.__listeners:
        self.__listeners[eventName].append(list)
    else:
        self.__listeners[eventName] = [list]

    return list


def __removeListener(list):
    self = JS("this")

    for eventName in self.__listeners:
        if list in self.__listeners[eventName]:
            JS("""$wnd.google.maps.event.removeListener(list);""")
            self.__listeners[eventName].remove(list)
            return
    # if we get here, there is nothing to remove,
    # the listener specified doesn't exist or does not belong to this object


def __clearListeners(eventName):
    self = JS("this")

    JS("""$wnd.google.maps.event.clearListeners(this, eventName);""")
    if eventName in self.__listeners:
        del self.__listeners[eventName]


def __clearInstanceListeners():
    self = JS("this")

    JS("""$wnd.google.maps.event.clearInstanceListeners(this);""")
    self.__listeners = {}
