#<ImportSpecificModules>
import collections
import copy
import numpy
import tables
import os
import ShareYourSystem as SYS
import sys
#</ImportSpecificModules>

#<DefineLocals>
JoinStr='__'
JoinDeepStr='/'
BasingLocalTypeStr="Shaper"
BaseClass=getattr(SYS,SYS.getClassStrWithTypeStr(BasingLocalTypeStr))
#</DefineLocals>

#<DefineClass>
class JoinerClass(BaseClass):
	
	@SYS.HookerClass(**{'AfterTuplesList':[(BaseClass,"init")]})
	def init(self):

		#<DefineSpecificDo>
		self.JoinedOrderedDict=collections.OrderedDict()		#<NotRepresented>
		self.JoinedDatabasePointer=None							#<NotRepresented>
		#</DefineSpecificDo>

	@SYS.HookerClass(**{'BeforeTuplesList':[("<TypeStr>","join")],'AfterTuplesList':[("Featurer","model")]})
	def model(self,**_KwargVariablesDict):
	def model(self,_ModelStr="",**_DatabasingVariablesDict):
		"""Call the Output<HookStr> methods and return self.OutputedPointer (self by default)"""

		#debug
		print('Modeler model method')
		print('_ModelStr is ',_ModelStr)
		print('')

		#Reinit attributes
		LocalOutputedPointer=self
		if _ModelStr=="":
			_ModelStr=self.DatabasedDict['ModelStr']
		else:
			self.DatabasedDict=self['App_Model_'+SYS.getDoingStrWithDoStr(_ModelStr)+'Dict']
			if self.DatabasedDict!=None:
				if 'IsDatabasedBool' not in self.DatabasedDict:

					#set variables
					IsDatabasedBool=False
					ModelStr=_ModelStr
					DatabasingStr=SYS.getDoingStrWithDoStr(ModelStr)
					DatabasedStr=SYS.getDoneStrWithDoStr(ModelStr)
					ModeledSuffixStr=SYS.getClassStrWithTypeStr(DatabasedStr+'Model')
					DatabasedKeyStr=""

					#Put them in the DatabasedDict
					LocalVars=vars()
					map(
							lambda __GettingStr:
							self.DatabasedDict.__setitem__(__GettingStr,LocalVars[__GettingStr]),
							[
								'IsDatabasedBool',
								'ModelStr',
								'DatabasingStr',
								'DatabasedStr',
								'ModeledSuffixStr',
								'DatabasedKeyStr'
							]
						)

		#set IsDatabasingBool
		self.IsDatabasingBool=True
		
		#Hook methods
		for OrderStr in ["Before","After"]:
		
			#Definition the HookMethodStr
			HookingMethodStr='model'+OrderStr

			#Check that there is HookingMethods for it
			if HookingMethodStr in self.__class__.HookingMethodStrToMethodsListDict:

				#Call the specific Appended methods 
				for HookingMethod in self.__class__.HookingMethodStrToMethodsListDict[HookingMethodStr]:

					#Call the HookMethod
					OutputVariable=HookingMethod(self,**_DatabasingVariablesDict)

					if type(OutputVariable)==dict:
						if 'LocalDatabasingVariablesDict' in OutputVariable:
							LocalDatabasingVariablesDict=OutputVariable['LocalDatabasingVariablesDict']
						if 'LocalOutputedPointer' in OutputVariable:
							LocalOutputedPointer=OutputVariable['LocalOutputedPointer']

					#Check Bool
					if self.IsDatabasingBool==False:
						return LocalOutputedPointer

		#debug
		print('END Modeler model method')
		print('_ModelStr is ',_ModelStr)
		print('')

		#Return the OutputVariable
		return LocalOutputedPointer