/*
Class: Json
	Simple Json parser and Stringyfier, See: <http://www.json.org/>
*/

// Initialize variables that cannot be undefined
var ajaxProxy = null;
var flashProxy = null;
var proxyready = false;
var tempObj = null;

/*
	* @Class: Publisher
	* @desc: creates the subscriber array and sends events to subscribers
	*
	*	@method: initialize
	*		@desc: constructor, creates the empty subscribers array
	*
	* @method: send
	*		@desc: sends events to subscribers
	* 	@param: type => string, the type of event to send
	*		@param: data => JSON, the data to send with the event object
	*		@object: obj => the event object passed back to the subscriber
	*			@attribute: data => object, the data object passed in from the publisher.send call
	*			@attribute: type => string, the type of event
	*			@attribute: element => conditional, only sent if the subsciber is not flahs, a reference to the subscriber element
	*
	* @method: subscribe
	*		@desc: add the element to the subscribers array in the specified publisher object
	*		@param: subscriber => string or element, the name of the subscriber object
	*		@param: type => string, the type of event to subscribe to
	*
	* @method: unsubscribe
	*		@desc: removed the element from the subscribers array in the specified publisher object
	*		@param: subscriber => string or element, the name of the subscriber object
	*		@param: type => string, the type of event to subscribe to
*/
var Publisher = $.inherit({
	__constructor: function () {
		this.subscribers = [];
	},
	send: function (eventType, eventData) {
		if (this.subscribers[eventType] != undefined) {
			$.each(this.subscribers[eventType], function(i, el) {
				var _obj = {
					'data': eventData,
					'type': eventType
				};
				if (el.tagName != "EMBED" && el.tagName != "OBJECT") {
					_obj.element = el;
					eval("el.on"+eventType+"(_obj)");
				} else {
		      		eval("el.on"+eventType+"(_obj)");
				}
			});
		}
	},
	subscribe: function (subscriber, eventType) {

		;;; console.log("subscriber :: " + subscriber + " eventType :: " + eventType);

		if ($type(subscriber) == "string") {
			subscriber = $('#' + subscriber)[0];
		}
		if (!this.subscribers[eventType]) {
			this.subscribers[eventType] = [];
		}
		if (eventType == "proxyready") {
		//	console.log('------------> proxy ready but not true: '+proxyready);
		}
		if (eventType == "proxyready" && proxyready == true) {
		//	console.log('------------> proxy ready true: '+proxyready);
			subscriber.onproxyready({ready: true});
		}
		if (this.subscribers[eventType] != subscriber) {
			this.subscribers[eventType].push(subscriber);
			return true;
		} else {
			return false;
		}
	},
	unsubscribe: function (subscriber, eventType) {
		this.subscribers[eventType].remove(subscriber);
	}
});

function dispatchLanguageEvent(lang) {
	pub.send('languagechange',{languageCode: lang});
}

/*
	* @Class: AjaxProxy
	* @desc: allows request/response of JSON formatted data across domains through an invisible flash movie
	*
	* @method: initialize
	*		@desc: constructor, creates a flash movie in the DOM with the ID of "Proxy" and makes the responder method available to Flash
	*
	* @method: send
	*		@desc: send a request to the flash proxy
	*		@param: data => JSON, the JSON object to send with the request
	*
	*	@method: responder
	*		@desc: the callback function for a response from the flash proxy
	*		@param: success => boolean
	*		@param: data => JSON, object containing the response from the request
*/
var AjaxProxy = $.inherit({
	__constructor: function (instance) {
	//	;;; console.log("proxy init");
		this.callback = "";
		this.instance = instance;
		
		$("<div/>", {
			id: "ajaxProxy"
		}).prependTo("body");
		
		var _so = new SWFObject(getProxyLocation(), "Proxy", "1", "1", "9", null, false, 'high', null, null);
	//	_so.addParam("wmode", "transparent");
		_so.addVariable("js_id", "Proxy");
		_so.addVariable("policyUrl", getPolicyLocation());
		_so.addVariable("readyCallback", this.instance+".ready");
		_so.write("ajaxProxy");
	},
	ready: function (success) {
		if (success == "true") {
			//;;; console.info("[ PROXY ] ::proxy ready");
			proxyready = true;
			pub.send("proxyready",{ready: true});
			ajaxProxy.send({
				controller: 'login',
				method: '__init__'
			},"widgetLoginFlow.ready");
			FlowInit();
		}
	},
	send: function (json, callback) {
		$('#Proxy')[0].sendRequest(getRpcLocation(), 'POST', jsonString(json), this.instance+".responder", callback);
	},
	responder: function (success, data, callback) {

		var _json_obj = decode_utf8_obj(eval("("+unescape(data)+")"));
		tempObj =  _json_obj;
		//console.dir(_json_obj);
		// dispatch events, if any
		if (_json_obj.events != undefined) {
			$.each(_json_obj.events, function (i, o) {
				// redirect the page is the redirect event is present
				if (o.type == "redirection") {
					if (o.secure) {
						window.location.href = getSecureBase() + o.uri;
					} else {
						window.location.href = getNonSecureBase() + o.uri;
					}
				} else {
					pub.send(o.type, o);
				}
			});
		}

		// call the supplied callback function
		if (success == "true") {
			var callbackParts = callback.split(".");
			 if ($(callbackParts[0]) != false) {
		 		eval(callbackParts[0]+"."+callbackParts[1]+"(_json_obj)");
			 }
		}
	}
});






/*
	* @Class: Flow
	* @desc: the class the manages flow related functions, form handling, etc...
*/
var Flow = $.inherit({
	__constructor: function (ctrl, instance) {
		console.log(ctrl);
		this.data = new Object();
		this.instance = instance;
		this.ctrl = $("#" + ctrl);
		// set the content areas for partial loads
		if(ctrl == "profile") {
			this.content = $(".inner", $("#" + this.instance))[0];
		} else if (ctrl == "phone") {
			this.content = $(".phoneInner", $("#" + this.instance))[0];
			if($("#ringtones").length) {
				this.ctrl = $("#ringtones");
		 	} else if ($("#wallpapers").length) {
		 		this.ctrl = $("#wallpapers");
		 	}
		} else {
			this.content = $(".inner", this.ctrl)[0];
		}
		
		if($(".title", this.ctrl)[0]) {
			this.header = ($(".title", this.ctrl)[0]);
			this.header.origHeight = this.header.scrollHeight;
			;;; console.log("js[Flow.initialize]: header: "+this.header);
			;;; console.info("js[Flow] header height: " + this.header.scrollHeight);
		}
		
		if($(".title", this.ctrl)[0]) {
			this.actionBar = ($("#bar", this.ctrl)[0]);
			this.actionBar.origHeight = this.actionBar.scrollHeight;
			;;; console.log("js[Flow.initialize]: actionBar: "+this.actionBar);
			;;; console.info("js[Flow] actionBar height: " + this.actionBar.scrollHeight);
		}
		;;; console.log("js[Flow.initialize]: content: "+this.content);
		this.content.origHeight = this.content.scrollHeight;
		;;; console.info("js[Flow] content height: " + this.content.scrollHeight);
		
		ajaxProxy.send({
			controller: ctrl,
			method: '__init__'
		}, this.instance+".update");
	},
	clear_errors: function () {
		// clear all errors to reset error state for all responses
		;;; console.warn("js[Flow.clear_errors] CLEARING ALL ERRORS");
		$('.error', this.ctrl).each(function (i) {
			$(this).removeClass("error");
		});
		$('.errorMessage', this.ctrl).each(function (i) {
			$(this).remove();
		});
	},
	add_error: function (el, msg) {
		$(el).addClass("error");
		error_message = $(document.createElement("p")).addClass('errorMessage');
		error_message.html(msg);
		if($('#error-list', this.ctrl).length == 0){
			error_message.appendTo($(el));
		} else {
			error_message.appendTo($('#error-list', this.ctrl));
		}
	},
	init_form: function (resp) {
		$('#submit', this.ctrl).each(function (i) { $(this).css('visibility','visible'); })

		;;; console.log("js[Flow.init_form - 2009]: "+this.id);
		var _flow = this;

		resetImageStyles();

		this.clear_errors();

		//global error handling
		if (resp.errors != undefined && resp.errors.length > 0) {
			throbber.hide();
			scroll(0,0);
			$('.specialErrorMessage', this.ctrl).each(function (i) {
				$(this).remove();
			});
			$.each(resp.errors, function (i, obj) {
				;;; console.warn("js[Flow.error] GLOBAL: "+obj);
				_flow.add_error($("#__global__"),obj);
			});
		}

		if (resp.response_code == "ERROR_FATAL") {
			throbber.hide();
			$("#__global__", this.ctrl).addClass("error");
			_flow.add_error($("#__global__", this.ctrl),"FATAL ERROR");
			;;; console.error("Unspecified FATAL ERROR from server, check instance logs");
		}

		$('a.js_Next', this.ctrl).click( function () {
			throbber.show();
			_flow.load_next($(this).attr('href'));
			$(this).hide();
			return false;
		});

		// init all the fields in this form
		var fields = new Array;
		$('form :input', this.ctrl).each(function (i) {
		 	if (this.type != "submit" && this.type != "image") {
		 		fields.push(this);
			}
		});
		

		//init all error outputs
		var errors = $('.js_ErrorHandler', this.ctrl);

		//populate form fields
		if (resp.data != undefined && $('form', this.ctrl).length > 0) {
			this.populate_form(resp, fields, errors);
		}
	//	;;; console.log("js[Flow.init_form]: fields");
		// serialize form data into json object for submission
		
		var form_obj = new Object();
		form_obj["data"] = new Object();

		
		$('form', this.ctrl).each( function (i) {
			
			;;; console.log("js[Flow.init_form]: form " + _flow.id);
			$(this).one('submit', function (e) {
				e.preventDefault();
				;;; console.log("js[Flow.init_form]: onsubmit " + _flow.id);

				throbber.show();

				if (_flow.flow_submit != undefined) {
					;;; console.log("js[Flow.init_form]: flow_submit " + _flow.id);
					_flow.flow_submit(resp, _flow);
				}
					
				$.each(fields, function (i, el) {
					;;; console.log("js[Flow.submit]: field: "+el.name + " <-> " + el.value);
					var sections = this.name.split(".");
					if (form_obj["data"][sections[0]] == undefined) form_obj["data"][sections[0]] = new Object();
					if (form_obj["data"][sections[0]][sections[1]] == undefined) form_obj["data"][sections[0]][sections[1]] = new Object();
					if (sections.length == 2) {
						if (this.type == "radio") {
							if ($(this).hasClass("js_boolean") && this.checked) {
								form_obj["data"][sections[0]][sections[1]]["value"] = this.value;
							} else if (!$(this).hasClass("js_boolean")) {
								form_obj["data"][sections[0]][sections[1]][el.id] = (this.checked == true) ? "true":"false";
							}
						} else if (this.type == "checkbox") {
							form_obj["data"][sections[0]][sections[1]]["value"] = (this.checked == true) ? "true":"false";
						} else {
							form_obj["data"][sections[0]][sections[1]]["value"] = this.value;
						}
					} else if (sections.length == 3) {
						form_obj["data"][sections[0]][sections[1]][sections[2]] = (this.type != "checkbox") ? this.value : this.checked.toString();
					}
				});
				var form_action = $(this).attr("action").split("/");
				form_obj["controller"] = form_action[form_action.length - 2];
				form_obj["method"] = form_action[form_action.length - 1];

				//send json object to server through ajaxProxy
				ajaxProxy.send(form_obj, _flow.instance+".update");
				if ($('#submit', $(this)).length > 0) $('#submit', $(this)).hide();
				return false;
			});
		});
		// run flow specific form function, created in flow init in (controller).js
		if (this.flow_form != undefined) {
			;;; console.log("js[Flow.init_form]: flow_form " + this.id);
			this.flow_form(resp, _flow);
		}
	},
	populate_form: function (resp, fields, errors) {
		;;; console.info("js[Flow.populate_form]: "+this.ctrl);
		;;; console.dir(resp);
		var _flow = this;

		if ($('#submit', this.ctrl).length > 0) $('#submit', this.ctrl).show();

		$('a.js_Next', this.ctrl).each( function (i) {
			$(this).show();
		});

		// check and display errors
		if (resp.response_type == "TYPE_ERROR") {
			throbber.hide();
			errors.each(function (i) {
				if (this.id != undefined && this.id != "" && eval("resp.data."+this.id) != undefined && eval("resp.data."+this.id+".error") != undefined) {
					_flow.add_error(this,eval("resp.data."+this.id+".error"));
				}
				scroll(0,0);
			});
		}

		// loop through and populate field values
		
		$.each(fields, function (i, el) {
			if (el.type != "password" && !$(el).hasClass('captcha') && !$(el).hasClass('js_noPopulate')) {
				;;; console.log("js[Flow.populate_form]: el " + el.name + " " + el.type);
				_flow.populate_field(el, resp);
			}
		});
		

		// run flow specific form function, created in flow init in (controller).js.jsp
		if (this.flow_populate != undefined) {
			;;; console.log("js[Flow.populate_form]: flow_populate " + this.id);
			this.flow_populate(resp);
		}
	},
	populate_field: function (el, resp) {
		if (eval("resp.data."+el.name) != undefined) {
			if (el.type != "radio" && el.type != "checkbox" && el.type != "textarea" && el.type != "select-one") {
				el.value = eval("resp.data."+el.name+".value");
				;;; console.log("js[Flow.populate_field]: " + el.name + " -> " + el.value);
			} else if (el.type == "select-one") {
				$.each(el.options, function (i, o) {
					//;;; console.log("js[Flow.populate_field]: " + el.name + " -> " + o.value + ", eval(resp.data."+el.name+".value) -> " + eval("resp.data."+el.name+".value"));
					if (o.value == eval("resp.data."+el.name+".value")) {
						o.selected = true;
					}
				});
			} else if (el.type == "radio" && eval("resp.data."+el.name+"."+el.id) != undefined) {
				el.checked = eval("resp.data."+el.name+"."+el.id);
			} else if (el.type == "checkbox") {
				el.checked = eval("resp.data."+el.name) == "true" || eval("resp.data."+el.name) == true;
			} else if (el.type == "textarea") {
				el.innerHTML = eval("resp.data."+el.name+".value");
			} else {
				;;; console.error("js[Flow.populate_field]: No type specified");
			}
		} else {
			;;; console.error("js[Flow.populate_field]: No data for field " + "resp.data."+el.name);
		}
	},
	update: function (resp) {
		// do some fancy content update dealy with animations and stuff
		;;; console.info("js[Flow.update]");

		this.data = resp;

		if (this.flow_update != undefined) {
			;;; console.log("js[Flow.flow_update]: flow_update " + this.id);
			console.dir(resp);
			this.flow_update(resp);
		}

		// follow next action directive
		if (resp.action == "partial") {
			;;; console.log("js[Flow.update]: content "+this.content.className);
			;;; console.log("js[Flow.update]: header "+this.header.className);
			;;; console.log("js[Flow.update]: actionBar "+this.actionBar.className);
			variant = (resp.variants.length > 0) ? ";"+resp.variants[0] : "";
			if (this.content != "") this.load_partial(getCxroot() + "/" + resp.controller + "/" + resp.view + variant + "!content", resp, this.content, null);
			//if (this.header != "") this.load_partial(getCxroot() + "/" + resp.controller + "/" + resp.view + variant + "!header", resp, this.header, null, false);
			if (this.actionBar != "") this.load_partial(getCxroot() + "/" + resp.controller + "/" + resp.view + variant + "!actionBar", resp, this.actionBar, null, false);
			$('#tracking').attr("src", getCxroot()+"/"+resp.controller+"/"+resp.view+"!ads");
		} else if (resp.action == "stay") {
			this.init_form(resp);
		}

	},
	load_partial: function (partial, resp, target, transition, init) {
		
		if (resp == undefined) resp = this.data;

		if (init != false) this.clear_errors();
		
		target = $(target);

		;;; console.log("js[Flow.load_partial]: part: "+partial+" target: "+target.attr('class')+" init: "+init);
		var _flow = this;
		var qString = (partial.indexOf("?") != -1) ? "&" : "?";
		$.ajax({
			url: partial+qString+new Date().getTime(),
			type: 'GET',
			success: function (ajx) {
				if (target == _flow.content) {
					if (target.parent().attr('id') != 'vanocpoll')
						target.css('background-color','#fff');
				}
				//update content
				;;; console.log("js[Flow.ajax complete]");
				if (transition != "skip") {
					var curHeight = target.height();

					throbber.show();
					target.css('overflow',"hidden");
					target.css('height',curHeight);
					target.animate({
						opacity: 0
					}, 1000, function() {
						;;; console.log("js[Flow.fadeOut onComplete]: "+target.attr('class'));
						target.html('');
						var container = $(document.createElement("div")).attr('id', 'js_ContentContainer');
						container.html(ajx);
						container.appendTo(target);
						var newHeight = container.height();
						;;; console.log("js[Flow.height onStart]: "+target.attr('class')+" "+target.height());
						target.animate({
							height: newHeight
						}, 1000, function() {
							;;; console.log("js[Flow.height onComplete]: "+target.attr('class')+" "+target.height());
							;;; console.info("js[Flow.fadeIn]: "+target.attr('class'));
							target.animate({
								opacity: 1
							}, 1000, function() {
								throbber.hide();
								target.css('filter', '');
								resetImageStyles();
								// run flow specific form function, created in flow init in (controller).js.jsp
								if (_flow.flow_after != undefined) {
									;;; console.log("js[Flow.populate_form]: flow_after " + _flow.id);
									_flow.flow_after(resp);
								}
							});
							if (init != false) _flow.init_form(resp);
							target.css('height','auto');
						});
					});
				} else {
					;;; console.log("js[Flow.ajax html update]: "+target.attr('class'));
					target.html(ajx);
					if (init != false) _flow.init_form(resp);
				}
			}
		});
	},
	load_next: function (uri) {
		;;; console.log("js[Flow.load_next] uri:"+uri);
		var path = uri.split("/");
		var json = {
			controller: path[path.length - 2],
			method: path[path.length - 1]
		};
		ajaxProxy.send(json, this.instance+".update");
	}
});

var Throbber = $.inherit(
	{
		show: function (){
			if (this.__self.enabled == true) {
				$('#Throbber').css('margin-top',($(window).scrollTop()-43)+"px");
				$('#Throbber').css('display','block');
			}
		},
		hide: function () {
			$('#Throbber').css('display','none');
		}
	},
	{
		enabled: true
	});

/*
 * Declare global functions
*/


// $type function from mootools must be overwritten because flash elements are returning type 'function' when they need to retun as 'element'
function $type(obj){
	if (obj === null || obj === undefined) return false;
	var type = typeof obj;
	if (obj instanceof Function) type = 'function';
	else if (obj.nodeName){
		if (obj.nodeType == 3 && !(/\S/).test(obj.nodeValue)) type = 'textnode';
		else if (obj.nodeType == 1) type = 'element';
	}
	if (type == 'object'){
		if (obj.htmlElement) return 'element';
		if (obj.push) return 'array';
		if (obj.nodeName){
			switch (obj.nodeType){
				case 1: return 'element';
				case 3: return obj.nodeValue.match(/\S/) ? 'textnode' : 'whitespace';
			}
		}
	}
	return type;
};


// overwrite mootools jsonString to fix string esaping
jsonString = function(obj){
	switch ($type(obj)){
		case 'string':
			obj = obj.replace(new RegExp('(["\\\\])', 'g'), '\\$1');
			obj = obj.replace(new RegExp("\\n", "g"), "\\n");
			obj = obj.replace(new RegExp("\\t", "g"), "\\t");
			obj = obj.replace(new RegExp("\\r", "g"), "\\r");
			obj = obj.replace(new RegExp("\\f", "g"), "\\f");
			return '"'+obj+'"';
		case 'array':
			return '['+ obj.map(function(ar){
				return jsonString(ar);
			}).join(',') +']';
		case 'object':
			var string = [];
			for (var property in obj) string.push('"'+property+'":'+jsonString(obj[property]));
			return '{'+string.join(',')+'}';
	}
	return String(obj);
};

// make console calls safe for other browsers
function disableFireBug() {

	var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
		"group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];

	window.console = {};

	for (var i = 0; i < names.length; ++i)
		window.console[names[i]] = function() {}

}

function getQueryVariable(variable) {
  var query = window.location.search.substring(1);
  var vars = query.split("&");
  for (var i=0;i<vars.length;i++) {
    var pair = vars[i].split("=");
    if (pair[0] == variable) {
      return pair[1];
    }
  }
	return null;
}

function encode_utf8(s) {
  return unescape(encodeURIComponent(s));
}

function decode_utf8(s) {
  return decodeURIComponent(escape(s));
}

function decode_utf8_obj(o) {

	if (typeof(o) == 'object') {

		for(var key in o) {
			var corrected_value = decode_utf8_obj(o[key]);
			var corrected_key = decode_utf8(key);
			delete o[key];
			o[corrected_key] = corrected_value;
		}
	} else if (typeof(o) == 'array') {

		for(var key in object) {
			o[key] = decode_utf8_obj(o[key]);
		}
	} else if (typeof(o) == 'string') {
		o = decode_utf8(o);
	}

	return o;
}


function noOp () {
	//empty function for callbacks that should be null
}

function pop (url, args) {
	var nameBuster = new Date();
	if (args == undefined) {
		args = 'width=550,height=650,directories=no,location=no,menubar=no,resizable=no,scrollbars=yes,status=no,toolbar=no';
	}
	window.open(getCxroot()+url,'popup'+nameBuster.getTime(),args);
}

function resetImageStyles () {
	if(typeof DD_belatedPNG != 'undefined') {
		DD_belatedPNG.fix('#intro img, #smalldaddies, #smalldaddies img, #brand-bar, .title img, #nav img, #brand-bar img, #widget img, #action-bar img, #Throbber img, #pinIncentive img, #search, #qk_search, .img');
	}
}

/*
	* @Function: Init
	* @desc: master init function, performs all tasks on DOM after DOM ready
*/
$(document).ready(function() {
	;;; console.log("js[Init] page init");
	
	
	//rounded corners for IE
	function roundCorners() {
		$(".title").corner("top");
		$('#nav ul li > a, .title ul li > a').each(function(){
			$(this).width($(this).width());
		}).corner("top");
		$(".inner_border .inner").corner("bottom").parents(".inner_border").corner("bottom");
		$(".inner_border_full .inner").corner().parents(".inner_border_full").corner();
	}
	roundCorners();

	// initialize the proxy
	if (isProxy()) ajaxProxy = new AjaxProxy("ajaxProxy");
	if (isProxy()) flashProxy = ajaxProxy; //for backward compatibility with flash calls to the proxy

	// set all forms to inactive until the flow initializes
	$('form', this.ctrl).submit(function () {
		return false;
	});

	// initialize the throbber for general use
	throbber = new Throbber();

	// add tracking iframe to keep it outsite our dom for performance
	
	var tracking = $("<iframe/>", {
		id: "tracking",
		name: "tracking",
		src: getCxroot()+"/"+getJctrl()+"/"+getJview()+"!ads"
	}).prependTo("body");
	
	pub.subscribe(tracking[0], 'login');
	var trackingLang = (getLanguage() == "fr") ? "_fr" : "";
	tracking[0].onlogin = function() {
		;;; console.warn("login iframe track");
	};
	
	
	//main nav rollovers
	$("#nav ul li:not(.active) a, .title ul li:not(.active) a").hover(
		function () {
			$(this).children(".off").hide();
			$(this).children(".on").show();
		},
		function () {
			if(!$(this).parent().hasClass("hover")) {
				$(this).children(".on").hide();
				$(this).children(".off").show();
			}
		}
	);
		
	
	//subnav 'view details' rollover
	$('.subnav a.image').hover(function(){ $(this).find('.view_overlay').show() }, function(){ $(this).find('.view_overlay').hide();});
	
	
	//main nav slidedown	
	var config = {
		sensitivity: 1, // number = sensitivity threshold (must be 1 or higher)
		interval: 100, // number = milliseconds for onMouseOver polling interval  
		over: down, // function = onMouseOver callback (REQUIRED)
		timeout: 100, // number = milliseconds delay before onMouseOut
		out: up // function = onMouseOut callback (REQUIRED)
	};
	
	$('#nav .subnav').parent().hoverIntent( config );
	
	function down () {
		$(this).addClass("hover");
		$('#brand-bar').css('border-color', '#ececec');
		$(this).children(".subnav").animate({ height: 85 }, 200);
		$('#brand-bar').css('border-color', '#ececec').animate({ top: 85 }, 200);
	}
	
	function up () {
		$(this).removeClass("hover");
		$(this).children(".subnav").animate({ height: 0 }, 200);
		$('#brand-bar').css('border-color', '#fff').animate({ top: 0 }, 200);
		$(this).not(".active").children().children(".on").hide();
		$(this).not(".active").children().children(".off").show();
	}
	
	//Add helped span to input and textarea fields.
	//$('input.sh').wrap('<span class="top_shadow"><span class="left_shadow"></span></span>');
	//$('textarea.sh').wrap('<span class="top_shadow_noh"><span class="left_shadow"></span></span>');
	
	
	
	//widget messages animation
	function wMessages() {
		var messages = $("#messages span");
		var current = 0;
		function showMessage() {
			var message = messages.eq(current);
			messages.eq(current - 1).hide();
			//temp for launch since backend doesnt support CDATA for links
			if(message.text() == 'Want a Sweet Movie Ticket Offer?*') {
				message.html("<a href='" + getCxroot() + "/pin'>" + message.text() + "</a>");
			} else if (message.text() == 'Une belle offre cinéma, ça te dit?*') {
				message.html("<a href='" + getCxroot() + "/pin'>" + message.text() + "</a>");
			}
			message.show().animate({top: [-4, 'swing']}, 200).animate({top: [0, 'swing']}, 200);
			++current;
		}
		messages.each(function(i) {
			setTimeout(showMessage, i * 4000); //2nd message will start at 4 seconds
		});
	}
	wMessages();
	
	
	//pin entry in nav
	$("#pin-entry input").focus(function () {
		if(this.defaultValue == $(this).val()) {
			$(this).val("");
		}
	});
	
	$("#pin-entry input").blur(function () {
		if($(this).val() == "") {
			$(this).val(this.defaultValue);
		}
	});
	
	$("#pin-entry a").click(function () {
		var pin = $("#pin-entry input").val()
		if(pin != $("#pin-entry input")[0].defaultValue) {
			ajaxProxy.send({
				controller: 'pin',
				method: 'pinwidgetEnter',
				data: {
					pinentry: {
						pin: {
							type: "text",
							value: pin
						},
						rulesregs: {
							value: true
						}
					}
				}
			}, "pinEntryFlow.update");
			throbber.show();
		}
		return false;
	});
	
	if($('#widget').length > 0){
		var bar = {MAXWIDTH: 134, MAXPINS: 20};
		var pin_width = bar.MAXWIDTH / bar.MAXPINS;
		var cur_pin_width = (bar.MAXPINS - $('#meter #progress').attr('rel')) * pin_width;
		$('#meter #progress').css('width', cur_pin_width);
	}
	
	$('#reward .inner, #latest .inner').click(function() {
		window.location = $(this).children("a").attr("href");
	});
	
	$("#login_widget #email").val(readCookie("email"));
	
	$("#login_widget #submit").click(function () {
		var email = $("#login_widget #email").val();
		var password = $("#login_widget #passwd").val();
		var rememberme = $("#login_widget #rememberme")[0].checked;
		if(email != "" && password != "") {
			ajaxProxy.send({
				controller: 'login',
				method: 'start',
				data: {
					builtin: {
						email: {
							value: email
						},
						password: {
							value: password
						}
					},
					startlogin: {
						rememberme: {
							value: rememberme
						}	
					}
				}
			}, "widgetLoginFlow.update");
			throbber.show();
		}
		return false;
	});

});

var pinEntry = $.inherit({
	__constructor: function() {
	},
	update: function(resp) {
		if (resp.response_code == 'ERROR_STQ') {
			throbber.hide();
			window.location = getCxroot() + "/pin/stq";
		} else if(resp.response_code != "NO_ERROR_QUICK_SUBMIT") {
			throbber.hide();
			window.location = getCxroot() + "/pin/enter/" + resp.data.pinentry.pin.value;
		} else {
			$("#pin-entry input").val($("#pin-entry input")[0].defaultValue);
			var cacheBuster = new Date();
			$.get(getCxroot() + "/scripts/balance.jsp?" + cacheBuster.getTime(), function(data) {
				throbber.hide();
  				$('#balance').fadeOut(500, function () {
  					$(this).html(data).fadeIn();
  				});
			});
			if(resp.attributes.is_incentive_active) {
				ppInit(resp.attributes["pin-entries"], 20);
			}

		}
	}
});

var widgetLogin = $.inherit({
	__constructor: function() {
	},
	update: function(resp) {
		if(resp.response_code == "ERROR_VALIDATION_FAILED") {
			throbber.hide();
			$("#login_widget form").hide();
			$("#login_widget #errors").show().html("<p>" +  resp.data.builtin.email.error + "</p><p><a href='"+getCxroot()+"/login'>" + (getLanguage() == 'en' ? 'Please try again!' : 'Essaie de nouveau!') + "</a></p>");
			$("#login_widget #errors a").click(function () {
				$("#login_widget #errors").hide();
				$("#login_widget form").show();
				return false;
			});
		} else if(resp.response_code != "NO_ERROR") {
			throbber.hide();
			$("#login_widget form").hide();
			$("#login_widget #errors").show().html("<p>" +  resp.errors[0] + "</p><p><a href='"+getCxroot()+"/login'>" + (getLanguage() == 'en' ? 'Please try again!' : 'Essaie de nouveau!') + "</a></p>");
			$("#login_widget #errors a").click(function () {
				$("#login_widget #errors").hide();
				$("#login_widget form").show();
				return false;
			});
		} else {
			throbber.hide();
			window.location.reload();
		}
	},
	ready: function(resp) {
		var ready = true;
	}
});

var pinEntryFlow = new pinEntry();
var widgetLoginFlow = new widgetLogin();
/*
	* @Function: FlowInit
	* @desc: default flow init, will be overridden by page specific init function 99% of the time
*/
var FlowInit = function () { };

// Create global instance of Publisher
var pub = new Publisher();

// disable firebug for live and ie
if (!isLive()) {
	try {
		console.dir();
	} catch (err) {
		disableFireBug();
	}
} else {
	disableFireBug();
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return "";
}

function updatePoints() {
	var cacheBuster = new Date();
	$.get(getCxroot() + "/scripts/balance.jsp?" + cacheBuster.getTime(), function(data) {
			$('#balance').fadeOut(500, function () {
				$(this).html(data).fadeIn();
			});
	});
}

(function($){

    /***
    * fadeIn() and fadeOut() now removes filter attribute in IE to resolve
    * clearType issues in IE6 and IE7. Can be short-circuited by setting
    * cancel to true.
    */
    var _fadeIn = $.fn.fadeIn;

    $.fn.fadeIn = function(easing, callback, cancel) {
        return _fadeIn.call(this, easing, function(){
            if(jQuery.browser.msie && !cancel) {
            	alert("test");
                $(this).get(0).style.removeAttribute('filter');
            }
            if($.isFunction(callback)) callback();
        });
    }

    var _fadeOut = $.fn.fadeOut;

    $.fn.fadeOut = function(easing, callback, cancel) {
        return _fadeOut.call(this, easing, function() {
            if(jQuery.browser.msie && !cancel) {
            	alert("test");
                $(this).get(0).style.removeAttribute('filter');
            }
            if($.isFunction(callback)) callback();
        });
    }

})(jQuery);