/// <reference path="C:\References\jquery-1.4.1-vsdoc.js" />

// ********************************************************************
// 
// Manheim Retail Marketing
// ********************************************************************
// Copyright © 2010 Manheim Retail Marketing.
//
//  Summary
// ******************************
// $Workfile: Binder.js $
// Notes:		Template file for creating standard java script files.
//
// File History Information
// ************************
// Created on:					    
// Last Modified:					$Modtime: 13/09/10 8:11 $
// Original Author:					Marc Lancashire
// Last Modified by:				$Author: Schjelderupj $
// Last JS Lint:					22/10/2009 13:00
//
// Source Control Information
// **************************
// File Version:					$Revision: 10 $
// VSS Location:					$Archive: /Manheim.Portfolio/Manheim.Portfolio.Web.UI.Client.Assets/assets/js/mrm/lib/ui/binders/1.0/Binder.js $
//
// ********************************************************************

// Check / create namespace
if (!mrm.global.isNamespaceDefined("mrm.lib.ui.binders"))
{
	mrm.global.createNamespace("mrm.lib.ui.binders", "1.0");
}


// Class definition
mrm.lib.ui.binders.Binder = Object.subClass(
{
	
	/*
	=============================
	CONSTANTS
	=============================
	*/
	// trace settings
	"TRACE"					: true,
	"TRACE_PREFIX"			: "mrm.lib.ui.binders.binder",
	"_tracing"				: {},	
	"TRACE_BINDING_PREFIX"	: " >>>> ",
	
	// event names
	"MRM_RUN_ALL"				: "MRM-RUN-CONTROL-BINDINGS",
	"MRM_RUN_ONE"				: "MRM-RUN-CONTROL-BINDING",
	"MRM_RUN_INSTANCE"			: "MRM_RUN_CONTROL_INSTANCE",
	
	// internal arrays
	"_binders"				: [],
	"_bindings"				: [],
	
	/*
	=============================
	CONSTRUCTOR
	=============================
	*/
	"init" : function (tracing)
	{
		var _this = this;
        this._tracing = tracing;
		
		if (!this._tracing)
		{
			this._tracing = new mrm.utilities.Tracing(this.TRACE, this.TRACE_PREFIX);
		}
		
		// add event handler to run the internal control bindings
		$(document).bind(this.MRM_RUN_ALL,
			function (e)
			{
				_this.bindControls(e);
			}
		);
		
		// add event handler to run single control binding
		$(document).bind(this.MRM_RUN_ONE,
			function (e, binding, binder)
			{
				_this.bindControl(e, binding, binder);
			}
		);

			// add event handler to run control bindings by instance id
		$(document).bind(this.MRM_RUN_INSTANCE,
			function(e, instanceId, jqContent)
			{
				_this.bindControls(e, instanceId, jqContent);
			}
		);
	},
	
	/*
	=============================
	PUBLIC MEMBERS
	=============================
	*/
	
	// use the internal bindings and binders to add dynamic functionality to the document
	// this is the handler for a document level event of run control bindings
	"bindControls" : function (jqEvent, instanceId, jqContent)
	{
		var controlBindings = (instanceId) ? this.findControlBindingInstances(instanceId) : this._bindings;
		var jqSourceContent = (jqContent) ? jqContent : null;
		
		this._tracing.addTrace("Start Bind [Binders(" + this._binders.length + "), Bindings(" + this._binders.length + ")]");		     

        for (var i = 0; i < controlBindings.length; i = i + 1)
		{
			var tbp, bindStatus;
			
			tbp = "[" + i + "] ";
			
			this._tracing.addTrace(tbp + "Start control binding.");

			bindStatus = this.bindControl(jqEvent, controlBindings[i], null, jqSourceContent);
			
			if (bindStatus)
			{
				this._tracing.addTrace(tbp + "Successful bind.");
			}
			else
			{
				this._tracing.addTrace(tbp + "Failed bind .");
			}
		}
		
		this._tracing.addTrace("End Bind");
	},
	
	// binds a control using the binding and binder provided, binder is optional if not provided an internal binder is looked up
	// this is the hander for a document level event of run control binding
	"bindControl" : function (jqEvent, binding, binder, jqSourceContent)
	{
		if (binding === null)
		{
			return false;
		}
		
		var tbp, bindingName, binderName, controlBinder, selector, instanceId, bindStatus, jqSelectedElements;
		
		bindingName		= binding.name;
		binderName		= binding.binderName;
		controlBinder	= (binder)? binder : this.getControlBinder(binderName);
		selector		= binding.selector;
		instanceId		= binding.instanceId;
		
		tbp = ">>>>>>>> [" + bindingName + "] - [" + selector + "] - ";
				
		this._tracing.addTrace(tbp + "Start.");
		
		// check if we have a control binder
		if (!controlBinder)
		{
			this._tracing.addTrace(tbp + "No binder provided or found in internal collection [" + binderName + "]");
			return false;
		}
		
		// get elements to bind
		jqSelectedElements = (jqSourceContent) ? $(selector, jqSourceContent) : $(selector);
		this._tracing.addTrace(tbp + "Found " + jqSelectedElements.length + " elements to bind.");
		
		// carry out binding
		bindStatus = controlBinder.bindControl(jqSelectedElements, instanceId, binding.settings);
		
		this._tracing.addTrace(tbp + "End.");
		
		return bindStatus;
	},
	
	// finds a control binder in the internal binders array using the provided binder name
	"getControlBinder" : function (binderName)
	{
		var binder;
		
		for (var i = 0; i < this._binders.length; i = i + 1)
		{
			if (this._binders[i].BINDER_NAME === null)
			{
				this._tracing.addTrace("Missing binder name, please ensure any binders are set with a binder name.");
			}
			else if (binderName === this._binders[i].BINDER_NAME)
			{
				binder = this._binders[i];
				break;
			}
		}
		
		return binder;
	},
	
	// add a control binder to the internal binders collection
	"addControlBinder" : function (controlBinder, useBinderTrace)
	{
		// ensure all binders use a common tracing util
		if (this._tracing && (useBinderTrace && useBinderTrace !== true))
		{
			controlBinder._tracing = this._tracing;
		}
		
		// add binder
		this._binders[this._binders.length] = controlBinder;
		
		// return a reference to the control binder
		return controlBinder;
	},
	
	// add a control binding to the internal collection
	"addControlBinding" : function (controlBinding)
	{
		this._bindings[this._bindings.length] = controlBinding;
		
		// return a reference to the control binding
		return controlBinding;
	},
	
	// find control bindings by instance id
	"findControlBindingInstances" : function(instanceId)
	{
		var instances = [];
		
		for (var i = 0; i < this._bindings.length; i = i + 1)
		{
			if (this._bindings[i].instanceId === instanceId)
			{
				instances[instances.length] = this._bindings[i];
			}
		}

		return instances;
	},

	// public method to get the tracing utility
	"tracing" : function ()
	{
		return this._tracing;
	},
	
	"properties" : function()
	{
		var properties = "";
		
		properties = properties + "binders = " + this._binders.length + ", ";
		properties = properties + "bindings = " + this._bindings.length + ".";
		
		return properties;
	}
	
	/*
	=============================
	PRIVATE MEMBERS
	=============================
	*/
	
	
}
);
