﻿var BindableCollection			= function ( )
{
	var self					= this ;
	
	self.base					= BaseClass ;
	self.base( ) ;
	
	var baseInitalise			= self.initalise ;
	self.name					= "Menu" ;
	
	self.boundControlId			= "" ;
	self.className				= "" ;

	self.TemplateText			= "" ;
	self.htmlElementTag			= "Item" ;
	self.isTemplateReady		= false ;
	self.isTemplateBusy			= false ;
	self.templateUrl			= "" ;

	self.isDataLoadedOnInitalise = true ;
	
	self.reloadedNotification	= null ;
	self.isReloadedNotificationShownOnLoad	= false ;
	
	var	onGetItemsCompleted		= [ ] ;
	var	onGetItemsChanged		= [ ] ;
	var _count					= 0 ;
	var isOnLoadBuildComplete	= false ;

	var formattedValues			= new Object( ) ;

	self.count					= function ( )
	{
		return					_count ;
	} ;

	self.saveTemplateText		= function( text )
	{
		self.TemplateText		= text ;
		self.isTemplateReady	= true ;
		self.isTemplateBusy		= false ;
		return					true ;
	} ;

	self.getTemplate			= function( )
	{
		self.isTemplateBusy		= true ;
		self.isTemplateReady	= false ;
		var httpRequest			= new HttpRequest( ) ;

		httpRequest.url			= self.templateUrl ;
		httpRequest.processText	= self.saveTemplateText ;

		httpRequest.initalise( ) ;
		httpRequest.prepareRequest( ) ;
		httpRequest.makeRequest( ) ;

		return					true ;
	} ;

	self.getItems				= function( )
	{
		eval( self.className + "( self.onGetItems ) ; " ) ;
		return					true ;
	} ;
	
	self.onGetItems				= function( result )
	{
		if ( result )
		{
			if ( result.value )
			{
				if ( self.isTemplateReady )
				{
					var	iLoopCount ;
					var item ;
					var innerHtml			= "" ;

					for ( iLoopCount = 0 ; iLoopCount < result.value.length ; iLoopCount++ )
					{
						item				= result.value[ iLoopCount ] ;
						innerHtml			= innerHtml + self.renderItem( item , iLoopCount ) ;

						fireOnGetItemsChanged( item ) ;
					}
					return		updateBoundControl( innerHtml , result );
				}
				else
				{
					if ( self.isTemplateBusy == false )
					{
						self.getTemplate( ) ;
					}
					setTimeout( function( ) { self.onGetItems( result ) ; } , 100 ) ;
					return		true ;
				}
			}
			else if ( result.error && result.error.Message )
			{
				self.raiseMessage( "ERROR :: " + result.error.Message ) ;
			}
			else
			{
				return			updateBoundControl( "" ,result ) ;
			}
		}
		return					false;
	} ;

	self.addBlankItem			= function( newItem )
	{
		var newHtml				= self.renderItem( newItem , self.count + 1 ) ;
		var itemParser			= document.createElement( "div" ) ;
		itemParser.innerHTML	= newHtml ;
		var iLoopCount ;
		var items				= [ ] ;
		for ( iLoopCount = 0 ; iLoopCount < itemParser.childNodes.length ; iLoopCount++ )
		{
			items.push( itemParser.childNodes[ iLoopCount ] ) ;
		}
		for ( iLoopCount = 0 ; iLoopCount < items.length ; iLoopCount++ )
		{
			document.getElementById( self.boundControlId ).appendChild( items[ iLoopCount ] ) ;
		}

		return					true ;
	} ;

	self.renderItem				= function( item , index )
	{
		var replacedKeys		= new Object( );

		var itemParser			= document.createElement( "div" ) ;
		var itemProperties		= null ;

		var itemIsGuid			= false ;
		var itemIsJsDate		= false ;
		var itemHtmlDecode		= false ;
		var itemHtmlEncode		= false ;
		var itemFormat			= "" ;
		var itemNullValue		= "" ;
		var itemNullOrEmptyValue= "" ;
		var itemEmptyValue		= "" ;
		var	itemIsNullGiven			= false ;
		var	itemIsNullOrEmptyGiven	= false ;
		var	itemIsEmptyGiven		= false ;
	
		var	ElementRegEx		= new RegExp( "<" + self.htmlElementTag + ":[^<]+?/>|<" + self.htmlElementTag + ":[^<]+?></" + self.htmlElementTag + ":[^<]+?>" , "gim" ) ;
		var	itemRegEx			= /:\w+|:#/ ;

		var	html				= self.TemplateText ;
		var elementMatches		= html.match( ElementRegEx ) ;

		var eMatchLoopCount ;
		for ( eMatchLoopCount = 0 ; eMatchLoopCount < elementMatches.length ; eMatchLoopCount++ )
		{
			var replacedKey = replacedKeys[ elementMatches[ eMatchLoopCount ] ] ;
			if ( string.isNullOrEmpty( replacedKey ) )
			{
				itemParser.innerHTML= elementMatches[ eMatchLoopCount ] ;
				itemProperties	= itemParser.childNodes[ 0 ] ;
				
				itemIsGuid			= false ;
				itemIsJsDate		= false ;
				itemHtmlDecode		= false ;
				itemHtmlEncode		= false ;
				itemFormat			= "" ;
				itemNullValue		= "" ;
				itemNullOrEmptyValue= "" ;
				itemEmptyValue		= "" ;
				itemIsNullGiven			= false ;
				itemIsNullOrEmptyGiven	= false ;
				itemIsEmptyGiven		= false ;

				var iAttributeLoopCount ;
				var attribute ;
				for ( iAttributeLoopCount = 0 ; iAttributeLoopCount < itemProperties.attributes.length ; iAttributeLoopCount++ )
				{
					attribute	= itemProperties.attributes[ iAttributeLoopCount ] ;
					if ( attribute.name == "format" )
					{
						itemFormat		= attribute.nodeValue ;
					}
					else if ( attribute.name == "isguid" && ( attribute.nodeValue == "true" || attribute.nodeValue == "1" ) )
					{
						itemIsGuid		= true ;
					}
					else if ( attribute.name == "isjsdate" && ( attribute.nodeValue == "true" || attribute.nodeValue == "1" ) )
					{
						itemIsJsDate	= true ;
					}
					else if ( attribute.name == "htmldecode" && ( attribute.nodeValue == "true" || attribute.nodeValue == "1" ) )
					{
						itemHtmlDecode	= true ;
					}
					else if ( attribute.name == "htmlencode" && ( attribute.nodeValue == "true" || attribute.nodeValue == "1" ) )
					{
						itemHtmlEncode	= true ;
					}
					else if ( attribute.name == "nullvalue" )
					{
						itemNullValue		= attribute.nodeValue ;
						itemIsNullGiven		= true ;
					}
					else if ( attribute.name == "nulloremptyvalue" )
					{
						itemNullOrEmptyValue= attribute.nodeValue ;
						itemIsNullOrEmptyGiven	= true ;
					}
					else if ( attribute.name == "emptyvalue" )
					{
						itemEmptyValue		= attribute.nodeValue ;
						itemIsEmptyGiven	= true ;
					}
				}

				var	itemMatches	= elementMatches[ eMatchLoopCount ].match( itemRegEx ) ;
				if ( itemMatches != null )
				{
					var iMatchLoopCount ;
					for ( iMatchLoopCount = 0 ; iMatchLoopCount < itemMatches.length ; iMatchLoopCount++ )
					{
						var value					= "" ;
						var key						= itemMatches[ iMatchLoopCount ].substr( 1 ) ;
						var formattedString			= "" ;
						if ( key == "#" )
						{
							formattedString			= index ;
						}
						else
						{
							formattedString			= item[ key ] ;
						}


						if ( itemIsNullOrEmptyGiven && string.isNullOrEmpty( formattedString ) )
						{
							formattedString			= itemNullOrEmptyValue ;
						} 
						else if ( itemIsNullGiven && formattedString == null )
						{
							formattedString			= itemNullValue ;
						} 
						else if ( itemIsEmptyGiven && formattedString != null && formattedString.length == 0 )
						{
							formattedString			= itemEmptyValue ;
						} 

						if ( string.isNullOrEmpty( itemFormat ) == false )
						{
							if ( itemIsJsDate && string.isNullOrEmpty( formattedString ) == false )
							{
								value				= formattedString.toString( itemFormat ) ;
							}
							else if ( string.isNullOrEmpty( formattedString ) == false && itemIsGuid && itemFormat == "N" && formattedString.length > 35 )
							{
								value				= Guid.format( itemFormat , formattedString ) ;
							}
							else
							{
								var formattedValueKey = "_" + formattedString + "{0:" + itemFormat + "}" ;
								var formattedValue = formattedValues[ formattedValueKey ] ;
								if ( typeof formattedValue == "undefined" || formattedValue == null )
								{
									if ( typeof value == "number" )
									{
										formattedString = AjaxProHelper.FormatNumber( "{0:" + itemFormat + "}" , formattedString ) ;
									}
									else
									{
										formattedString	= AjaxProHelper.FormatString( "{0:" + itemFormat + "}" , formattedString ) ;
									}
									if ( formattedString != null )
									{
										if ( formattedString.error != null )
										{
											alert( "FORMATTING ERROR :: " + formattedString.error.Message ) ;
										}
										else
										{
											value	= formattedString.value ;
											formattedValues[ formattedValueKey ]	= value ;
										}
									}
								}
								else
								{
									value			= formattedValue ;
								}
							}
						}
						else
						{
							value	= formattedString ;
						}

						if ( itemHtmlDecode )
						{
							var formattedValueKey = "_" + formattedString + "{HtmlDecode}" ;
							var formattedValue = formattedValues[ formattedValueKey ] ;
							if ( typeof formattedValue == "undefined" || formattedValue == null )
							{
								formattedString	= AjaxProHelper.HtmlDecode( value ) ;
								if ( formattedString != null )
								{
									if ( formattedString.error != null )
									{
										alert( "FORMATTING ERROR [HtmlDecode] :: " + formattedString.error.Message ) ;
									}
									else
									{
										value	= formattedString.value ;
										formattedValues[ formattedValueKey ]	= value ;
									}
								}
							}
							else
							{
								value			= formattedValue ;
							}
						}
						else if ( itemHtmlEncode )
						{
							value				= string.htmlEncode( value ) ;
						}

						replacedKeys[ elementMatches[ eMatchLoopCount ] ] = "true" ;
						html		= html.replace( new RegExp( elementMatches[ eMatchLoopCount ] , "gim" ) , value ) ;
					}
				}
			}
		}
		_count++ ;
		return					html ;
	} ;

	var updateBoundControl		= function( innerHtml , result )
	{
		var oldHtml				= document.getElementById( self.boundControlId ).innerHTML ;
		document.getElementById( self.boundControlId ).innerHTML = innerHtml ;
		document.getElementById( self.boundControlId ).scrollTop = 0 ;
		
		if ( ( self.isReloadedNotificationShownOnLoad || isOnLoadBuildComplete == true ) && self.reloadedNotification != null && self.reloadedNotification.show != null && typeof self.reloadedNotification.show == "function" && document.getElementById( self.boundControlId ).innerHTML != oldHtml )
		{
			setTimeout( self.reloadedNotification.show , 5 ) ;
		}
		if ( isOnLoadBuildComplete == false )
		{
			isOnLoadBuildComplete	= true ;
		}
		try
		{
			if ( myLytebox )
			{
				setTimeout( myLytebox.updateLyteboxItems , 5 ) ;
			}
		}
		catch( ex ){}
		setTimeout( function( ) { fireOnGetItemsCompleted( result ) ; } , 5 ) ;
		return		true ;
	} ;

	var fireOnGetItemsCompleted		= function( result )
	{
		var func ;
        for ( var i = 0; i < onGetItemsCompleted.length; i++ )
		{
			func					= onGetItemsCompleted[ i ] ;
			if ( typeof func == "function" )
			{
				if ( func( result ) == false )
				{
					return			false ;
				}
			}
        }
        return						true ;
    } ;

	self.registerOnGetItemsCompleted	= function( func )
	{
		if ( typeof func == "function" )
		{
			onGetItemsCompleted.push( func ) ;
			return					true ;
		}
		alert( "[" + self.name + "][registerOnGetItemsCompleted] Delagates of the type " + typeof func + " are not supported." ) ;
		return						false ;
	} ;

	var fireOnGetItemsChanged		= function( item )
	{
		var func ;
        for ( var i = 0; i < onGetItemsChanged.length; i++ )
		{
			func					= onGetItemsChanged[ i ] ;
			if ( typeof func == "function" )
			{
				if ( func( item ) == false )
				{
					return			false ;
				}
			}
        }
        return						true ;
    } ;

	self.registerOnGetItemsChanged	= function( func )
	{
		if ( typeof func == "function" )
		{
			onGetItemsChanged.push( func ) ;
			return					true ;
		}
		alert( "[" + self.name + "][registerOnGetItemsChanged] Delagates of the type " + typeof func + " are not supported." ) ;
		return						false ;
	} ;

	self.initalise				= function( )
	{
		// Must set the response of this into a variable or the method will itself return true and not continue.
		if ( baseInitalise( ) == false )
		{
			return				false ;
		}
		if ( self.isDataLoadedOnInitalise == true )
		{
			if ( self.getItems( ) == false )
			{
				return			false ;
			}
		}

		return					true ;
	} ;

	// Object create OK	
	return						true ;
} ;
