#**************************************************************
#
#  Licensed to the Apache Software Foundation (ASF) under one
#  or more contributor license agreements.  See the NOTICE file
#  distributed with this work for additional information
#  regarding copyright ownership.  The ASF licenses this file
#  to you 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.
#
#**************************************************************
import uno
import unohelper

from com.sun.star.lang import IllegalArgumentException,XServiceInfo
from com.sun.star.uno import RuntimeException
from com.sun.star.beans import UnknownPropertyException
from test.testtools.bridgetest import TestData,XRecursiveCall,XBridgeTestBase

g_ImplementationHelper = unohelper.ImplementationHelper()
g_implName = "org.openoffice.comp.pyuno.PythonTestObject"

g_attribs = "RuntimeException", "Bool", "Char", "Byte", "Short", "UShort", \
            "Long", "ULong", "Hyper", "UHyper", "Float", "Double", "Enum", \
	    "String", "Interface", "Any" , "Sequence" , "Struct"

def assign( rData, bBool, cChar, nByte, nShort, nUShort, nLong, nULong, nHyper,\
	      nUHyper, fFloat, fDouble, eEnum, rStr, xTest, rAny  ):
    rData.Bool = bBool;
    rData.Char = cChar;
    rData.Byte = nByte;
    rData.Short = nShort;
    rData.UShort = nUShort;
    rData.Long = nLong;
    rData.ULong = nULong;
    rData.Hyper = nHyper;
    rData.UHyper = nUHyper;
    rData.Float = fFloat;
    rData.Double = fDouble;
    rData.Enum = eEnum;
    rData.String = rStr;
    rData.Interface = xTest;
    rData.Any = rAny;

class MyRecursiveCall( XRecursiveCall, unohelper.Base ):
      def callRecursivly( xCall, nToCall ):
	  if nToCall:
	     xCall.callRecursivly( self, nToCall -1 )

class SampleUnoComponent( XBridgeTestBase,XServiceInfo ):
      def __init__(self,ctx):
	  self.__dict__["callid"] = 0
	  self.__dict__["sequenceBroken"] = 0

      def transportAny( self, value ):
	  return value

      def raiseException( self, ArgumentPosition, Message, Context ):
	  raise IllegalArgumentException( Message, Context, ArgumentPosition )

      def raiseRuntimeExceptionOneway(self, Message, Context ):
	  raise RuntimeException( Message, Context )

      def setValues( self, bBool, cChar, nByte, nShort, nUShort, nLong,\
		     nULong, nHyper, nUHyper, fFloat, fDouble, eEnum, \
		     aString, xInterface, aAny, aSequence, aStruct ):
         self.__dict__["data"] = TestDataElements( bBool, cChar, nByte, nShort, nUShort, nLong,
	                  nULong, nHyper, nUHyper, fFloat, fDouble, eEnum, aStruct, xInterface,
			  aAny, aSequence )
         self.__dict__["Struct"] = aStruct

      def setValues2( self, bBool, cChar, nByte, nShort, nUShort, nLong, nULong,\
		      nHyper, nUHyper, fFloat, fDouble, eEnum,		\
		      aString, xInterface, aAny, aSequence, aStruct ):
          self.__dict__["Struct"] = TestData( cChar, nByte, nShort, nUShort, nLong, nULong, nHyper,\
	                                      nUHyper, fFloat, fDouble, eEnum, aStruct, xInterface,\
					      aAny, aSequence )
          self.__dict__["Struct"] = aStruct
	  return bBool, cChar, nByte, nShort, nUShort, nLong, nULong, nHyper, nUHyper, nULong, \
	         nHyper, nUHyper, fFloat, fDouble, eEnum, aStruct, xInterface, aAny,	       \
		 (aSequence[1],aSequence[0]), aStruct

      def getValues(self, a,b,c,d,e,f,g,h, i,j,k,l,m,n):
	  v = self.__dict__["data"]
	  return self.__dict__["Struct"],v.Bool, v.Char, v.Byte, v.Short, v.UShort, v.Long,	\
	         v.ULong, v.Hyper, v.UHyper, v.Float, v.Double, v.Enum, v.String, v.Interface,	\
		 v.Any, v.Sequence, self.__dict__["Struct"]

      def call( self, callid, nWaitMUSEC ):
	  if self.__dict__["callid"] >= callid:
	     self.__dict__["sequenceBroken"] = 1
	  else:
	     self.__dict__["callid"] = callid

      def callOneway( self, nCallId, nWaitMUSEC ):
	  call( nCallId, nWaitMUSEC )

      def sequenceOfCallTestPassed():
	  return self.__dict__["sequenceBroken"]

      def startRecursiveCall( xCall , nToCall ):
	  if nToCall:
	     xCall.callRecursivly( MyRecursiveCall(), nToCall -1 )

      def checkExistence( self, name ):
	  found = 0
	  for x in g_attribs:
	      if x == name:
		 found = 1
		 break
	  if not found:
	     raise UnknownPropertyException( "Property "+name+" is unknown", self )

      def __setattr__( self, name, value ):
	  checkExistence( name )
	  self.__dict__[name] = value

      def __getattr__( self, name ):
	  checkExistence( name )
	  return self.__dict__[name]

      def getSupportedServices( self ):
	  return g_ImplementationHelper.getSupportedServices(g_implName)
      def supportsService( self, ServiceName ):
	  return g_ImplementationHelper.supportsService( g_implName, ServiceName )
      def getImplementationName(self):
	  return g_implName


g_ImplementationHelper.addImplementation( \
	SampleUnoComponent,g_implName,("com.sun.star.test.bridge.PythonTestObject",),)

#g_ImplementationEntries = \
#    unohelper.ImplementationEntry(				\
#	      "org.openoffice.comp.SamplePythonComponent",	\
#	      ("com.sun.star.test.bridge.PythonTestObject",),	\
#	      SampleUnoComponent)				\
#	   ,
