YAHOO.namespace("Edutone");

//Widget base class
(function(){
	//Private variables
	var json = YAHOO.lang.JSON,
		lang = YAHOO.lang;
	var m_raw ;
	
	
	//Private methods
	
	//Constructor
	var Widget= function(raw){
		m_raw = raw;
		this.instantiate.apply(this, arguments);
	};
	
	Widget.EVENTS = {
		'dragdrop'	: true,
		'expand'	: true,
		'remove'	: true
	};
	
	var pm_bodywrap=function(content, id){
		return '<div class="gedget-body" id="widget-body-' + (id) + '">' + 'loading...' + '</div>';
	}
	
	//public properties and methods
	Widget.prototype = {
		//properties
		EVENTS : null,
		LIFECYCLE: null,
		_container:null,
		_body : null,
		_bodyHTML : "",
		_sync_frame:null,
		//methods
		instantiate:function(data){
			lang.augmentObject( this, data );	
			this.EVENTS 	= Widget.EVENTS;
			this.LIFECYCLE 	= [ 
				this.loadcomplete, 
				this.render, 
				this.load, 
				this.init ]; 
		},
		startLifeCycle:function(container){
			
			this._container = container;
			
			//Render widget Frame, and init body Object
			var content = pm_bodywrap("", this.id);
			this._container.innerHTML = this.t_headerHTML() + 
				content + this.t_footerHTML();
			this._body = YAHOO.util.Dom.get( "widget-body-" + this.id );
			this._sync_frame = YAHOO.util.Dom.get( "widget-session-sync-" + this.id );
			
			var fnCycle = this.LIFECYCLE.pop();
			fnCycle.call(this);
		},
		initCompleted:function(eventType, args){
			var resp = (args[0].responseText);
			var objResp = json.parse(resp);
			
			//First access. 
			this.setting.init_url = this.setting.init_url + "&" +  objResp.result;
			this._sync_frame.src = this.setting.init_url;
			
			var fnCycle = this.LIFECYCLE.pop();
			fnCycle.call(this);
		},
		initFailed:function(){
			//end do something display proper error msg
		},
		init:function(){
			//alert("loading widget" + this.id);
			this._body.innerHTML = "initializing...";
			if(this.setting.session_start_required)
			{
				//invoke asyncronous ajax loading
				var callback = {
					customevents:{
						onSuccess:this.initCompleted,
						onFailure:this.initFailed,
						onAbort:this.initFailed
					},
					scope:this,
				 	timeout: 600000	//60 seconds
				};
				
				YAHOO.util.Connect.initHeader('X-Signature', this.setting.session_signature );
				var request = YAHOO.util.Connect.asyncRequest(
						'GET', 
						this.setting.session_start_url, 
						callback, 
						'widget=' + this.id 
					);
			}
			else
			{
				//continue to load()
				var fnCycle = this.LIFECYCLE.pop();
				fnCycle.call(this);
			}
		},
		load:function(){
			this._body.innerHTML = "loading...";
		
			//invoke asyncronous ajax loading
			var callback = {
				customevents:{
					onSuccess:this.loadCompleted,
					onFailure:this.loadFailed,
					onAbort:this.loadFailed
				},
				scope:this,
			 	timeout: 600000	//60 seconds
			};
			
			YAHOO.util.Connect.initHeader('X-Signature', this.setting.session_signature );
			var request = YAHOO.util.Connect.asyncRequest(
					'GET', 
					this.setting.content_url, 
					callback, 
					'widget=' + this.id 
				);
		},
		loadCompleted:function(eventType, args){
			var resp = (args[0].responseText);
			try{
			var objResp = json.parse(resp);
			this._bodyHTML = objResp.result;
			//alert(this._bodyHTML );
			}catch(e)
			{
				alert("error occured:" + e.message);
			}	
			var fnCycle = this.LIFECYCLE.pop();
			fnCycle.call(this);
		
		},
		loadFailed:function(eventType, args){
			
		
		},
		
		render:function(){
			var oBody = document.getElementById('widget-body-' + this.id);
			//alert(this.t_bodyHTML());
			this._body.innerHTML = this._bodyHTML;
			var fnCycle = this.LIFECYCLE.pop();
			fnCycle.call(this);
		},
		
		toXHTML:function(){
			var retVal = this.t_headerHTML() + this.t_bodyHTML() + this.t_footerHTML();
			return retVal;
		},
		
		toString:function(){
			return json.stringify(m_raw);
		},
		
		//protected methods
		t_headerHTML : function()
		{
			return "this is WIDGET header";
		},
		
		t_bodyHTML : function()
		{
			return "this is WIDGET body";
		},
		
		t_footerHTML : function()
		{
			return "this is WIDGET footer";	
		}
	};
	
	
	
	YAHOO.Edutone.Widget = Widget;	
})();	//End of closure


//Extended Widget classes
(function(){
	//Constructor
	YAHOO.Edutone.SmallFixedIFrameWidget = function(raw){
		var fnSupperClass = YAHOO.Edutone.SmallFixedIFrameWidget.superclass.constructor;
		fnSupperClass.call(this,raw);
	};
	
	YAHOO.lang.extend( YAHOO.Edutone.SmallFixedIFrameWidget, YAHOO.Edutone.Widget, {
		//public template methods
		t_headerHTML : function()
		{
			return '\
		    <div id="widget" style=""> \
		      <div class="popup"> \
		        <table> \
		          <tbody> \
		            <tr> \
		              <td class="tl"/><td class="t"/><td class="tr"/> \
		            </tr> \
		            <tr> \
		              <td class="l"/> \
		              <td class="body"> \
		                <div id="widget_content" class="content"> \
						   <div id="widget-container-' + this.id + '" class="gedget-container">\
								<div class="passport-widget-heading">\
									<div class="block left"><b>' + this.title + '</b></div><div class="block right">'+ this.icon + '</div> \
								</div>';
		},
		
		t_bodyHTML : function()
		{
			return '\
				<iframe class="widget-content-frame"  src="' + this.setting.content_url + '"></iframe>\
				<iframe class="widget-session-sync" id="widget-session-sync-' + this.id + '" src=""></iframe>\
				';
		},
		
		t_footerHTML : function()
		{
			return '</div></div> \
						  <div class="widget-apps-browse-wrapper"> \
						  <button class="btn-look-for-apps" onmouseover="this.className=\'btn-look-for-apps-over\';" onmouseout="this.className=\'btn-look-for-apps\';" onclick="document.location.href=\'apps.php\';" ></button> \
						  </div> \
			              </td> \
			              <td class="r"/> \
			            </tr> \
			            <tr> \
			              <td class="bl"/><td class="b"/><td class="br"/> \
			            </tr> \
			          </tbody> \
			        </table> \
			      </div> \
			      <iframe class="widget-session-sync" id="widget-session-sync-' + this.id + '" src=""></iframe>\
			    </div>';	
		}
	}); 


	//**************** BIG WIDGET ****************//
	//Constructor
	YAHOO.Edutone.BigFixedIFrameWidget = function(raw){
		var fnSupperClass = YAHOO.Edutone.BigFixedIFrameWidget.superclass.constructor;
		fnSupperClass.call(this,raw);
	};
	 
	YAHOO.lang.extend( YAHOO.Edutone.BigFixedIFrameWidget, YAHOO.Edutone.Widget, {
		//protected methods
		t_headerHTML : function()
		{
			return '\
		    <div id="widget" style=""> \
		      <div class="popup"> \
		        <table> \
		          <tbody> \
		            <tr> \
		              <td class="tl"/><td class="t"/><td class="tr"/> \
		            </tr> \
		            <tr> \
		              <td class="l"/> \
		              <td class="body"> \
		                <div id="widget_content" class="content"> \
						   <div id="widget-container-' + this.id + '" class="gedget-container">\
								<div class="passport-widget-heading">\
									<b>' + this.title + '</b>\
								</div>';
		},
		
		t_bodyHTML : function()
		{
			return '\
				<iframe class="widget-content-frame"  src="' + this.setting.content_url + '"></iframe>\
				<iframe class="widget-session-sync" id="widget-session-sync-' + this.id + '" src=""></iframe>\
				';
		},
		
		t_footerHTML : function()
		{
			return '</div></div> \
			              </td> \
			              <td class="r"/> \
			            </tr> \
			            <tr> \
			              <td class="bl"/><td class="b"/><td class="br"/> \
			            </tr> \
			          </tbody> \
			        </table> \
			      </div> \
			    </div>';	
		}
	}); 

})();
 

/**
 * Widget factory Class.
 * It return widget instance based on the type of widget supplied
 * .@usage : YAHOO.Edutone.WidgetFactory.getInstance( data, type )
 * .@widgetData : widget data JSON object
 * .@type	    : type of the widget to be instantiated
 */
YAHOO.Edutone.WidgetFactory = function () {
	var _widgetClasses = {
		'SMALL-FIXED-IFRAME':YAHOO.Edutone.SmallFixedIFrameWidget,
		'BIG-FIXED-IFRAME'	:YAHOO.Edutone.BigFixedIFrameWidget
	}
		 
	return  {
		getInstance:function(widgetData){
			return new _widgetClasses[widgetData.type](widgetData);
		}
	};
}(); 


/**
 * Edutone Widget Manager Class.
 * It is an interface to HTML page.  Web page only need to interact with this class to get widget rendered.
 * .@see useful methods below 
 * .@register 	: to register a widget
 * .@render		: to render a widget 
 * .@type	    : type of the widget to be instantiated
 */
YAHOO.Edutone.WidgetManager = function () {
	//WidgetBridge Collection
	var _widgets={};
	
	return  {
		/**
		 * .register: function (widgetData, container) {
		 * .// transform the registering widgetData into WidgetBridget		//. 
		 * .// and register it into WidgetBridge Collection 				//.
		 * .>@widgetData : JSON widget data. 
		 * <.@ return the transformed WidgetBridge object
		 */
		register: function (widgetData) {			
			if(widgetData!=null)
			{
				_widgets[widgetData.id] = YAHOO.Edutone.WidgetFactory.getInstance(widgetData);
				return _widgets[widgetData.id];
			}else return null;
		},		
		syncronize:function(id,url)
		{
			//alert(id + url);	
			document.getElementById("widget-session-sync-" + id).src = url;
		},
		terminate:function(id, url)
		{
			document.getElementById("widget-session-sync-" + id).src = url;
		},
		syncronizeAll:function()
		{
			for(i in _widgets)
			{
				if(_widgets[i]!=null && _widgets[i].syncronize.url!="")
					YAHOO.Edutone.WidgetManager.syncronize(_widgets[i].id, _widgets[i].syncronize.url );
			}
		},
		
		/**
		 * .render : function(widget, where)
		 * .// render the particular widget into HTMLElement container //.
		 * .>@widget : it can be widgetData or widgetBridge
		 * .>@where 	: HTMLElement container
		 * <.@ N/A
		 */
		render : function(widget, where)
		{
			if(YAHOO.lang.isUndefined(widget)==false && YAHOO.lang.isObject(widget))
			{
				//document.getElementById(where).innerHTML = widget.toXHTML();
				var oDiv = YAHOO.util.Dom.get( where );
				widget.startLifeCycle(oDiv);
				
			}			
		} ,
		
		renderAtEnd: function(widget, container){
			if(YAHOO.lang.isUndefined(widget)==false && YAHOO.lang.isObject(widget))
			{
				var lastChild = YAHOO.util.Dom.getLastChild( container );
				var oDiv = document.createElement("div");
				YAHOO.util.Dom.setAttribute(oDiv, "style", "display:block;float:left;margin:5px;");
				YAHOO.util.Dom.setAttribute(oDiv, "id", "container-" + widget.id);
				YAHOO.util.Dom.insertAfter( oDiv , lastChild );
				widget.startLifeCycle(document.getElementById("container-" + widget.id) );
			}
		},
		
		getRegisteredWidget:function(widgetId){
			return _widgets[widgetId];
		},
		
		/**
		 * .renderAll : function(locationPreference)
		 * .// render all of the registered widgets into prefered HTMLElement container(s) //.
		 * .>@ locationPreference : a hash map of HTMLElements hashed by widgetID
		 * <.@ N/A
		 */
		renderAll : function(locationPreference)
		{
			for(i in _widgets)
			{
				if(_widgets[i]!=null){
					var where = locationPreference[ _widgets[i].id ];
					YAHOO.Edutone.WidgetManager.render( _widgets[i], where );
				}
			}
			/*var interval = 6000;	//default is 30 mins = 1800000
			var repeat = true;
		    YAHOO.lang.later( 1800000, YAHOO.Edutone.WidgetManager, "syncronizeAll", null, true);
		    */
		},
		renderListIn:function(list, container){
			for(i=0;i<list.length;i++)
			{
				var id = list[i];
				if(_widgets[ id ]!=null){
					YAHOO.Edutone.WidgetManager.renderAtEnd( _widgets[id], container );
				}
			}
		},
		
		renderList:function(list){
			for(id in list)
			{
				if(_widgets[id]!=null){
					var where = list[ id ];
					YAHOO.Edutone.WidgetManager.render( _widgets[id], where );
				}
			}
		}
		 
	};
}(); 


