# -*- coding: windows-1252 -*-

# sys.argv[1] - html file to open
# sys.argv[2] - directory containing pyAwesomium

import array
import os
import unittest
import sys

if __name__ == "__main__":
  if len(sys.argv) < 2:
    print "Usage: '%s' <pyAwesomium_path>" % os.path.basename(sys.argv[0])
    exit()
  
sys.path.append( sys.argv[1] )
print "pyAwesomium path is '%s'" % sys.argv[1]

HTML_FILE = os.path.join( os.path.dirname(__file__), "../html/tests/PythonUnitTest.html" )
print "HTML_FILE is '%s'" % HTML_FILE

import pyAwesomium

#-------------------------------------------------------------------------------

class MessageLogger( pyAwesomium.WebView.MessageLogger ):

  def __init__(self):
    pyAwesomium.WebView.MessageLogger.__init__(self)
    
  def log(self, msg):
    print msg

#-------------------------------------------------------------------------------

class WebViewListener( pyAwesomium.WebViewListener ):

  def __init__( self, view ):
    pyAwesomium.WebViewListener.__init__( self, view )
    self.loaded = False
    self.calledBack = False
    self.js_window = None
    self.js_confirm_loaded_message = None
    self.onChangeCursor_called = False
    
  def onBeginNavigation(self, url, frameName):
    print "onBeginNavigation", url, frameName
    
  def onBeginLoading(self, url, frameName, statusCode, mimeType):
    print "onBeginLoading"
    
  def onFinishLoading(self):
    print "onFinishLoading"
    self.loaded = True
    
  def onCallback(self, name, args_tuple):
    print "callback", name, repr(args_tuple)
    self.calledBack = True
    
  def onReceiveTitle(self, title, frameName):
    print "onReceiveTitle", title, frameName

  def onChangeTooltip(self, tooltip):
    print "onChangeTooltip", tooltip
    
  def onChangeCursor(self, cursor):
    self.onChangeCursor_called = True
    
  def js_confirm_loaded(self, message):
    self.js_confirm_loaded_message = message
    
  def javascript_setWindow(self, js_window=None):
    self.js_window = js_window

#-------------------------------------------------------------------------------

class UnitTestValues:

  def get_bool(self):
    return True

  def get_int(self):
    return 12

  def get_double(self):
    return 2.0

  def get_string(self):
    return "hello"

#-------------------------------------------------------------------------------

class Test(unittest.TestCase):

  def test_core(self):

    core = pyAwesomium.WebCore()
    core.setBaseDirectory( os.path.split(HTML_FILE)[0] )
    
    asyncRendering = False
    maxAsyncRenderPerSec = 70
    
    view = core.createWebView(640, 480, asyncRendering, maxAsyncRenderPerSec)
    
    listener = WebViewListener( view )
    logger = MessageLogger()
    
    view.setListener( listener )
    view.setMessageLogger( logger )
    
    view.setProperty("python", listener)
    view.setCallback("javascript_callback")
    
    view.loadFile( os.path.split(HTML_FILE)[1], "mainframe" )
    
    #
    
    while not listener.loaded:
      core.update()
        
    self.assert_( listener.js_confirm_loaded_message is not None )
    self.assertEqual( u"Unicode: éèàêç€", listener.js_confirm_loaded_message )
      
    # execute JS functions via the naive Awesomium interface
    
    value = view.executeJavascriptWithResult("get_bool()", "")
    self.assertEqual( True, value )
      
    value = view.executeJavascriptWithResult("get_int()", "")
    self.assertEqual( 12, value )
      
    value = view.executeJavascriptWithResult("get_double()", "")
    self.assertEqual( 2.0, value )
      
    value = view.executeJavascriptWithResult("get_string()", "")
    self.assertEqual( "hello", value )
    
    # execute JS functions via the window NPObject
    
    js_window = view.executeJavascriptWithResult("get_window()", "")
    
    test_invokeDefault = js_window()
    self.assertEqual( None, test_invokeDefault )
    del test_invokeDefault
    
    self.assertEqual( True, js_window.get_bool() )
    
    self.assertEqual( 12, js_window.get_int() )
    
    self.assertEqual( 2.0, js_window.get_double() )
    
    self.assertEqual( "hello", js_window.get_string() )
    
    # get the JS functions via the window NPObject, and execute the corresponding objects
    
    fn_value = js_window.get_bool
    self.assertEqual( True, fn_value() )
    del fn_value

    fn_value = js_window.get_int
    self.assertEqual( 12, fn_value() )
    del fn_value
    
    fn_value = js_window.get_double
    self.assertEqual( 2.0, fn_value() )
    del fn_value
    
    fn_value = js_window.get_string
    self.assertEqual( "hello", fn_value() )
    del fn_value
    
    # (regression test) try to create a race condition between Invoke and GetProperty
    
    print "(regression test) try to create a race condition between Invoke and GetProperty"
    
    for j in xrange(2):
      for i in xrange(50):
        view.executeJavascript("get_int()", "")
      for i in xrange(50):
        fn_value = js_window.get_int
        self.assertEqual( 12, fn_value() )
        del fn_value
    
    #
    
    #self.assert_( js_window.compare_python_values( UnitTestValues() ) )
    
    del js_window
    
    #
    
    #while not listener.calledBack:
    #  core.update()
      
    self.assert_( listener.js_window is not None )
    self.assertEqual( "<orphan javascript object>", listener.js_window )
    
    #
    
    pybuffer = " " * (640*480*4)
    view.render(pybuffer)
    
    #
    
    for i in xrange(64):
      view.injectMouseMove(i*2, i*2)
      core.update()
      view.render(pybuffer)
    
    self.assert_( listener.onChangeCursor_called )
    
    #
    
    view.setProperty("python", None)
    view.setListener(None)
    view.setMessageLogger(None)
    view.destroy()
    
    del listener

if __name__ == "__main__":

  del sys.argv[1:]
  unittest.main()