(function( $ )
{
	if ( typeof (Array.prototype.indexOf) == 'undefined' ) {
		Array.prototype.indexOf = function(item) {
			for(var i = 0; i < this.length; i++ ) {if ( this[i] == item )return i;}
			return -1;
		}
	}
	String.prototype.splitUrls = function() {
	    var urls = this.split(',http');
		for(var i = 0; i < urls.length; i++ ) {if ( i > 0 ) urls[i] = 'http' + urls[i];}
		return urls;
	}
	var debug = false;
	jQuery.fn.log = function (msg) {
		if ( debug && console )console.log("%s: %o", msg, this);
		return this;
    };
 
	jQuery.fn.extend({
		executeOnce: function(label,delay, fn, option) {return this.each(function() {jQuery.timer.delayExecute(this, delay, label, fn, option);});},
		stopExecution: function(label) {return this.each(function() {jQuery.timer.remove(this, label);});}
	});
	
	jQuery.extend({
		timer: {
			delayExecute: function(element, delay, label, fn, option) {
				var timer = jQuery.data(element, label);
				if ( timer ) {
					if ( timer.timerId ) {
						if ( option == 'block' ) return;
						window.clearTimeout(timer.timerId);
						timer.timerId = null;
					}
				} else {
					timer = {};
					jQuery.data(element, label, timer);
				}
				var timerId;
				var handler = function() {
					if ( timer.timerId == timerId ) {
						timer.timerId = null;
						fn.call(element);
					} else {
					}
				};
				timerId = timer.timerId = window.setTimeout(handler,delay);
			
			},
			remove: function(element, label) {
				var timer = jQuery.data(element, label);
				if ( timer ) {
					if ( timer.timerId ) {
						window.clearTimeout(timer.timerId);
						timer.timerId = null;
					}
				}
			}
		}
	});


	$.fn.document = function() {
		var element = this[0];
 		if ( element.nodeName.toLowerCase() == 'iframe' )
 			return element.contentWindow.document;
		else
			return $(this);
	};
	
  	var getTransparent = function(el){
  		for(var n=0;n<el.parents().length;n++){
			var parent = el.parents().get(n);
			var pBg = $.browser.safari ? $(parent).css("background") : $(parent).css("background-color");
			if(pBg!='' && pBg!='transparent'){
				return pBg;
			}
		}
		return '#FFF';
  	}

	$.fn.hoverClass = function(clsName) {
		this.bind('mouseover',function(e){$(this).addClass(clsName);}).bind('mouseout',function(e){$(this).removeClass(clsName);});
        return this;
	};
	
	$.fn.loadContent = function(url,data,callback,errorCallback ) {
		var parent = this;
		$.ajax({
			type: "GET",
			url: url,
			//data: $("#flip").serialize(),
			beforeSend: function(){
			},
			success: function(html){
				$(html).appendTo(parent).find('input:text').inputFields();
				callback(html);
			},
		    error: errorCallback
		});
	};
	
	var fadeFx = function( opts) {
		opts.showAnim	   = { opacity: 1 };
		opts.hideAnim   = { opacity: 0 };
		opts.cssBeforeShow = { opacity: 0,display:''};
		opts.cssAfterShow = { opacity:''};

		opts.hideSpeed = 100;
	    opts.showSpeed = 1200;
		opts.sync=true;
		opts.beforeHide.push(function(toHide){
		    var offset = toHide.position();
			this.cssBeforeHide = {top:offset.top + 'px',left:offset.left + 'px',opacity:1,zIndex:100000,position:'absolute'}; 
			this.cssAfterHide = {position:'',top:'',left:'',opacity:'',zIndex : '',display:'none'};
		})
		if ($.browser.msie) { 
			opts.beforeShow.push(function(toShow){
		    if ( this.dynamicLoad && toShow[0].tagName == 'IMG' && this.center ) {
		        var h = toShow.outerHeight();
		        var ph = toShow.parent().outerHeight();
				var m = (ph-h)/2;
				if ( m > 0 )
                	toShow.css('marginTop', m + 'px');
		    }
			});
		}
	};

	var vScrollFx = function( opts) {
		opts.hideAnim   = { height: 'hide' };
		opts.showAnim = { height: 'show' };
		opts.cssAfterShow = { display: '',top:'0px'}
		opts.hideSpeed = 1300;
	    opts.showSpeed = 1300;
	};

	var tossFx = function(opts) {
		if (opts.xOffset == 0 )
			opts.xOffset = 100;
		if ( opts.yOffset == 0 )
			opts.yOffset = 50;
		opts.beforeHide.push(function(toHide){
		    var offset = toHide.position();
			var color = getTransparent(toHide);
			this.cssBeforeHide = {top:offset.top + 'px',left:offset.left + 'px',opacity:1,zIndex:100000,backgroundColor:color,position:'absolute'};
			
			this.cssAfterHide = {position:'',top:0,left:0,opacity:'',zIndex : '',display:'none'};
			this.cssBeforeShow = {opacity:0,zInex:990000,display:''};//,verticalAlign: 'middle'};//top:'',left:'',position:'static'};
			this.cssAfterShow = {opacity:'',zIndex:''};
			this.hideAnim = {left: (offset.left + this.xOffset) + 'px', top: (offset.top - this.yOffset) + 'px',opacity:0};

		});
		if ( this.removeAfterHide ) {
			opts.afterHide.push(function(toHide){toHide.remove();});
		}
		if ($.browser.msie) { 
			opts.beforeShow.push(function(toShow){
		    	if ( this.dynamicLoad && toShow[0].tagName == 'IMG' && this.center ) {
		        	var h = toShow.outerHeight();
		        	var ph = toShow.parent().outerHeight();
					var m = (ph-h)/2;
					if ( m > 0 ) toShow.css('marginTop', m + 'px');
		    	}
			});
        }
		opts.showAnim = { opacity:1 };
		opts.sync = true;
		opts.hideSpeed = 1200;
		opts.showSpeed = 500;
	};

	var zoomFx = function(opts) {
		opts.beforeHide.push(function(toHide){
			var pw = toHide.parent().outerWidth();
			var ph = toHide.parent().outerHeight();
			var w = toHide.outerWidth();
			var h = toHide.outerHeight();
			var x = (pw-w)/2;
			var y = (ph-h)/2;
		    var offset = toHide.position();
			var color = getTransparent(toHide);
			this.cssBeforeHide = {top:offset.top + 'px',left:offset.left + 'px',width:w + 'px',height: h + 'px',opacity:1,zIndex:100000,backgroundColor:color,position:'absolute'};
			this.jqContentContainer.css('display','block');
			offset = this.jqHideTarget.position();

			this.hideAnim={width:this.jqHideTarget.outerWidth() + 'px',height:this.jqHideTarget.outerHeight() + 'px',top:offset.top + 'px',left: offset.left + 'px'};

		});
		if ( this.removeAfterHide ) {
			opts.afterHide.push(function(toHide){toHide.remove();});
		}
		opts.beforeShow.push(function(toShow){
		    var offset = this.jqShowSrc.position();
			var ws = this.jqShowSrc.outerWidth();
			var hs = this.jqShowSrc.outerHeight();
			var pw = this.jqContentContainer.outerWidth();
			var ph = this.jqContentContainer.outerHeight();
			var w = toShow.outerWidth();
			var h = toShow.outerHeight();
			var x = (pw-w)/2;
			var y = (ph-h)/2;
			var color = getTransparent(toShow);
			this.cssBeforeShow = {top:offset.top + 'px',left:offset.left + 'px',width:ws + 'px',height: hs + 'px',opacity:1,zIndex:100000,backgroundColor:color,position:'absolute'};
			if ( !$.browser.msie)
				this.cssAfterShow= {position:'',top:'',left:'',zIndex:'',marginTop:y + 'px'};
			var parent = this.jqContentContainer;
			//alert(parent.outerWidth() + ":" + parent.outerHeight());
			//alert(this.jqContentContainer.offset().left + ":" + this.jqContentContainer.offset().top);
			offset = this.jqContentContainer.position();
			//offset = this.jqContentContainer.parent().position();
			this.showAnim = { width: w + 'px',height: h + 'px',left: (offset.left + x)+ 'px',top: (offset.top + y)+ 'px'};

		});

		opts.sync = true;
		opts.hideSpeed = 200;
		opts.showSpeed = 200;
	};

	var zoomxFx = function(opts) {
		opts.beforeHide.push(function(toHide){
			var pw = toHide.parent().outerWidth();
			var ph = toHide.parent().outerHeight();
			var w = toHide.outerWidth();
			var h = toHide.outerHeight();
			var x = (pw-w)/2;
			var y = (ph-h)/2;
			this.cssBeforeHide = {};
			this.hideAnim={width:'hide'};
			if ($.browser.msie) { 
		    	//if ( this.dynamicLoad && toHide[0].tagName == 'IMG' && this.center ) {
		    	if ( this.center ) {
		        	var h = toHide.outerHeight();
		        	var ph = toHide.parent().outerHeight();
					var m = (ph-h)/2;
					if ( m > 0 ) toHide.css('marginTop', m + 'px');
		    	}
        	}

		});
		if ( this.removeAfterHide ) {
			opts.afterHide.push(function(toHide){toHide.remove();});
		}
		opts.beforeShow.push(function(toShow){
			var pw = toShow.parent().outerWidth();
			var ph = toShow.parent().outerHeight();
			var w = toShow.outerWidth();
			var h = toShow.outerHeight();
			var x = (pw-w)/2;
			var y = (ph-h)/2;
			this.cssBeforeShow = {};
			this.showAnim = { width:'show'};
			if ($.browser.msie) { 
		    	//if ( this.dynamicLoad && toShow[0].tagName == 'IMG' && this.center ) {
		    	if ( this.center ) {
		        	var h = toShow.outerHeight();
		        	var ph = toShow.parent().outerHeight();
					var m = (ph-h)/2;
					if ( m > 0 )
                		toShow.css('marginTop', m + 'px');
		    	}
        	}

		});

		//opts.sync = true;
		opts.hideSpeed = 800;
		opts.showSpeed = 1200;
	};
	
	var shuffleFx = function(opts) {
		opts.beforeHide.push(function(toHide){
			var w = toHide.parent().outerWidth();
			var offset = toHide.position();
			var offset2 = toHide.parent().position();
			var color = getTransparent(toHide);
			//toHide.css('background-color', color);
			this.cssBeforeHide = {top:offset.top + 'px',left:offset.left + 'px',zIndex:800000,position:'absolute',backgroundColor:color};
			this.cssAfterHide = {top:'',left:''};//,zIndex :'',position:''};//,opacity:''};
			this.hideAnim = {left: '-=' + (w+this.xOffset) + 'px',top:'-=' + this.yOffset + 'px'};//,opacity:.4};
			this.hideAnim2 = {left: '+=' + (w+this.xOffset) + 'px',top:'+=' + this.yOffset + 'px'};//,opacity:0};

			this.cssBeforeShow = {zIndex:990000,opacity:0,position:'absolute',backgroundColor:color};
			this.cssAfterShow = {zIndex: ''};
			this.showAnim = {opacity:1};

		});
		opts.doHideAnimate = function(jqToHide,jqToShow) {
			var mgr = this;
			jqToHide.animate(this.hideAnim, this.hideSpeed).animate(mgr.hideAnim2, mgr.hideSpeed, function() { //
					jqToHide.hide();
					mgr.doAfterHide(jqToHide);
            });
			this.doShow(jqToShow);
		}

		opts.beforeShow.push(function(toShow){
			
			var pw = toShow.parent().outerWidth();
			var ph = toShow.parent().outerHeight();
			var w = toShow.outerWidth();
			var h = toShow.outerHeight();
			var x = (pw-w)/2;
			var y = (ph-h)/2;
			this.cssBeforeShow = {};
			if ($.browser.msie) { 
		    	if ( this.center ) {
		        	var h = toShow.outerHeight();
		        	var ph = toShow.parent().outerHeight();
					var m = (ph-h)/2;
					if ( m > 0 )
                		toShow.css('marginTop', m + 'px');
		    	}
        	}

		});

		opts.sync = true;
		opts.hideSpeed = 500;
		opts.showSpeed = 100;

	};
	var replaceImage = function (jqToHide,jqToShow) {
		this.doBeforeHide(jqToHide);
		jqToHide.attr('src',jqToShow.attr('src'));
		this.doAfterShow(jqToShow);
	}
	var replaceContent = function (jqToHide,jqToShow) {
		this.doBeforeHide(jqToHide);
		jqToHide.hide();
		this.doAfterHide(jqToHide);
		jqToShow.show();			  
		this.doAfterShow(jqToShow);

	}
		
	var defaultDisplayMgr = {
	    fx:'',
		hideAnim: null,
	    hideSpeed: 0,
		cssBeforeHide : {},
		cssAfterHide : {},
		beforeHide : [],
		afterHide : [],
	    showAnim : null,
	    showSpeed:0,
		cssBeforeShow : {},
		cssAfterShow : {},
		beforeShow : [],
		afterShow : [],
		sync: false,
		removeAfterHide : false,
		xOffset :0,
		yOffset :0,
		doBeforeHide : function(jqToHide) {
			var param = [jqToHide];
			for(i=0; i < this.beforeHide.length; i++ )
				this.beforeHide[i].apply(this,param);
			jqToHide.css(this.cssBeforeHide);
		},
		doAfterHide : function(jqToHide) {
			var param = [jqToHide];
			for(i=0; i < this.afterHide.length; i++ )
				this.afterHide[i].apply(this,param);
			jqToHide.css(this.cssAfterHide);
			jqToHide.hide();
            if (typeof this.onHide == 'function') {
            	this.onHide();
			}
		},
		doBeforeShow : function(jqToShow) {
			var param = [jqToShow];
			for(i=0; i < this.beforeShow.length; i++ )
				this.beforeShow[i].apply(this,param);
			jqToShow.css(this.cssBeforeShow);
		},
		doAfterShow : function(jqToShow) {

			var param = [jqToShow];
			for(i=0; i < this.afterShow.length; i++ )
				this.afterShow[i].apply(this,param);
            jqToShow.css(this.cssAfterShow);
			jqToShow.css('opacity',1).show(); // opacity bit needed to handle reinit case
			if ($.browser.msie) jqToShow[0].style.removeAttribute('filter');
            if (typeof this.onShow == 'function') {
            	this.onShow();
            }
		},
		doHideAnimate : function(jqToHide,jqToShow) {
			var mgr = this;
			jqToShow.hide();
			jqToHide.animate(this.hideAnim, this.hideSpeed, function() { //
				jqToHide.hide();
				mgr.doAfterHide(jqToHide);
				if( !mgr.sync ) mgr.doShow(jqToShow);
            });
			if ( mgr.sync ) this.doShow(jqToShow);
		},
		doShowAnimate : function(jqToShow) {
			var mgr = this;
            jqToShow.animate(this.showAnim, this.showSpeed, function() {
				jqToShow.show();
				mgr.doAfterShow(jqToShow);
             });
		},
		doShow : function (jqToShow) {
			this.doBeforeShow(jqToShow);
 			if ( this.showAnim && this.showSpeed ) {
				this.doShowAnimate(jqToShow);
			} else {
				jqToShow.show();
				this.doAfterShow(jqToShow);
            }
		},
		doHide : function(jqToHide,jqToShow) {
			this.doBeforeHide(jqToHide);
 			if ( this.hideAnim && this.hideSpeed ) {
				this.doHideAnimate(jqToHide,jqToShow);
 			} else {
				jqToHide.hide();
				this.doAfterHide();
			    this.doShow(jqToShow);
	        }
		},
		toggleDisplay : function(jqToHide,jqToShow) {
			this.doHide(jqToHide,jqToShow);
		},
		init : function () {
			switch( this.fx ) {
				case 'toss':
					tossFx(this);
					break;
				case 'zoom':
					zoomFx(this);
					break;
				case 'vScroll':
					vScrollFx(this);
					break;
				case 'fade':
					fadeFx(this);
					break;
				case 'shuffle':
					shuffleFx(this);
					break;
				case 'replaceContent':
					this.toggleDisplay = replaceContent;
					break;
				case 'replaceImage':
					this.toggleDisplay = replaceImage;
					break;
			}

		}
	};
	
	var defaultContentMgr = {
		id : "contentMgr",
		display:$.extend({},defaultDisplayMgr),
		contents:null,
		urlSelect:null,
		activeIndex: 0,
		maxIndex:0,
		wrapIndex : true,
		dynamicLoad : false,
		removeAfter : false,
		isImage : false,
		urlList : null,
		jqContainer: null,
		jqContents : null,
		jqCacheContents : null,
		cache : false,
		slideShowDelay : 500,
		slideShowCycle : 2000,
		slideShowEnabled : false,
		beforeDynamicLoad : function () {
		},
		afterDynamicLoad : function () {
		},
		//initList : [],
		onShow : function () {
//it is possible that hide have not finish
			//this.resetActiveContent();
//do on certian condition only
			this.jqContents = this.jqContainer.find(this.contents);
			this.jqActiveContent = this.jqContents.filter(':visible');

			if ( this.slideShowEnabled )
				this.delayNext();
		},
		onHide : function () {
		},
		delayNext : function (delay) {
			if ( this.slideShowEnabled ) {
				var mgr = this;
				var handler = function () {
					mgr.next();
				}
				this.jqContainer.executeOnce(this.id+'sstimer',delay || this.slideShowCycle, handler, 'block');
			}
		},
		startSlideShow : function() {
			this.slideShowEnabled = true;
			this.delayNext(this.slideShowDelay);
		},
		stopSlideShow : function () {
			this.slideShowEnabled = false;
			this.jqContainer.stopExecution(this.id+'sstimer');
		},
		resetActiveContent : function () {
			var previous = this.jqActiveContent;
			this.jqActiveContent = this.jqContents.filter(':visible');
			if ( this.jqActiveContent.length > 1 ) {
				var idx = this.jqActiveContent.index(previous[0]);
				this.jqActiveContent = $(this.jqActiveContent[idx == 0 ? 1 :0 ]);
			}
		},
		switchToIndex : function(idx) {
			if ( idx != this.activeIndex ) {
				if ( this.cache ) {
					var url = this.urlList[idx];
					if ( this.urlList[url] ) {
						this.switchToContent(this.urlList[url]); 
						this.activeIndex = idx;
					} else {
						this.loadContent(url);
					}
				} else if ( this.dynamicLoad ) {
					this.loadContent(this.urlList[idx]);
				} else {
					this.switchToContent($(this.jqContents[idx]));
					this.activeIndex = idx;
				}
			}
		},
		switchToContent : function(jqTarget) {
			if ( this.jqContents.length > 1 )
				this.jqActiveContent = this.jqContents.filter(':visible');
			else
				this.jqActiveContent = this.jqContents;
			this.display.jqShowSrc = this.jqShowSrc;
			this.display.jqHideTarget = this.jqCurrent
			this.display.toggleDisplay(this.jqActiveContent,jqTarget);
		},
		previous : function() {
			if ( this.activeIndex > 1 ) {
				this.switchToIndex(this.activeIndex-1);
			} else if ( this.wrapIndex ) {
				this.switchToIndex(this.maxIndex);
			}
		},
		next : function() {
			if ( this.activeIndex < this.maxIndex ) {
				this.switchToIndex(this.activeIndex + 1);
			} else {
				if (this.wrapIndex || this.slideShowEnabled ) {
				this.switchToIndex(0);
				}
			}
		},
		loadContent : function (url,idx) {
			this.beforeDynamicLoad();
			if ( this.isImage ) {
				this.dynamicLoadImage(url);
			} else {
				//call  before dynamic load
				//opts.jqSelected.addClass('loading');
				var mgr = this;
				this.jqActiveContent.parent().loadContent(url,null,function(html) {mgr.afterLoad(url,$(html),false);},null);
			}
		},
		dynamicLoadImage : function (url) {
			var imgPreloader = new Image();
			var mgr = this;
			imgPreloader.onload=function(){
				mgr.afterLoad(url,$(imgPreloader),mgr.display.fx != 'replaceImage');
			}
			imgPreloader.src = url;
		},
		afterLoad : function (url,elem,append) {
			this.afterDynamicLoad();
			var index = this.urlList.indexOf(url);
			if ( append )
				elem.hide().appendTo(this.jqActiveContent.parent());
			//elem.find('input:text').inputFields();

			if ( this.cache	) {
				this.urlList[url] = elem;
				this.switchToIndex(index);
			} else {
				this.activeIndex = index;
				this.switchToContent(elem); 
			}
		},
		initContext : function () {
			this.resetActiveContent();
			if ( this.urlSelect || this.getUrls) {
				this.dynamicLoad = this.display.dynamicLoad = true;
				var urls;
				//for backward compatibility - should be remove
				if ( this.getUrls ) {
				    urls = this.getUrls();
					this.maxIndex = this.urlList.length -1;
				} else {
				    if ( this.urlSelect.charAt(0) == '[' && this.urlSelect.charAt(this.urlSelect.length - 1) == ']' ) {
				    //if ( this.urlSelect == '[img]' ) {
					    urls = this.jqContainer.attr(this.urlSelect.substring(1,this.urlSelect.length-1));
				    } else {
				        urls = this.jqContainer.find(this.urlSelect);
				        if ( urls.length > 0 ) {
					        urls = urls.attr('urls');
				        }
				    }
				    if ( urls.length > 0 ) {
					    this.urlList = urls.splitUrls();
					    this.maxIndex = this.urlList.length -1;
				    }
				}
				
				if ( this.isImage ) {
					this.activeIndex = urls.indexOf(this.jqContents[0].src);
				//else {
					//this.activeIndex = this.jqContents.index(this.jqActiveContent[0]);
				}
			} else {
				this.maxIndex = this.jqContents.length - 1;
				this.activeIndex = this.jqContents.index(this.jqActiveContent[0]);
			}
		},
		init : function () {
			var mgr = this;
			if ( this.jqContainer ) {
        		this.jqContents = this.jqContainer.find(this.contents);
			}
			if ( this.jqContents ) {
				this.display.jqContentContainer = this.jqContents.parent();
				this.initContext();
			}

			//replcae image only if dynamic and isImage
			if ( this.display.fx == '' ) {
				if ( this.dynamicLoad && this.isImage )
					this.display.fx = 'replaceImage';
				else
					this.display.fx = 'replaceContent';
			}
			if ( this.dunamicLoad && this.fx == 'toss' )
				this.display.removeAfterHide = true;
			this.display.init();
			this.display.onShow = function () {
				mgr.onShow();
			}
			this.display.onHide = function () {
				mgr.onHide();
			}
			//(this.initList.length);
			if ( this.initList )
			for(i=0; i < this.initList.length; i++ )
				this.initList[i].apply(this);

		}
	};
	$.fn.configureContentManager = function(options) {
		if ( options.contents == undefined )
        	options.contents = '>';

	    var settings = $.extend({},defaultContentMgr,options);
		settings.display=$.extend({},defaultDisplayMgr,options.display);
		settings.display.beforeHide = [].concat(defaultDisplayMgr.beforeHide);
		if ( options.display && options.display.beforeHide )
			settings.display.beforeHide.concat(options.display.beforeHide);
		settings.display.afterHide = [].concat(defaultDisplayMgr.afterHide);
		if ( options.display && options.display.afterHide )
			settings.display.afterHide.concat(options.display.afterHide);
		settings.display.beforeShow = [].concat(defaultDisplayMgr.beforeShow);
		if ( options.display && options.display.beforeShow )
			settings.display.beforeShow.concat(options.display.beforeShow);
		settings.display.afterShow = [].concat(defaultDisplayMgr.afterShow);
		if ( options.display && options.display.afterShow )
			settings.display.afterShow.concat(options.display.afterShow);
		var doClone = this.length > 1;
		this.each(function() {
			var config = doClone ? $.extend({},settings) : settings;
			config.jqContainer = $(this);
	//should create new copy ofdisplay----
			if ( doClone ) {
				config.display = $.extend({},settings.display);
			}

			config.init();
		    jQuery.data(this, config.id, config);
		});
		return this;

	};
	
	jQuery.fn.extend({
		startSlideShow: function() {
			this.each(function() {
		    	var contentMgr = jQuery.data(this, defaultContentMgr.id);
				if ( contentMgr )
					contentMgr.startSlideShow();
			});
			return this;
		},
		stopSlideShow: function() {
			return this.each(function() {
		    	var contentMgr = jQuery.data(this, defaultContentMgr.id);
				if ( contentMgr )
					contentMgr.stopSlideShow();
			});
		}
	});


	/*
	 * $('conatiner').hoverSlideShow(options)
	 */
	$.fn.hoverSlideShow = function(options) {
		this.configureContentManager(options);
		return this.each(function() {
			$(this).bind('mouseleave',function(e) {
				$(this).stopSlideShow();
			}).bind('mouseenter',function(e) {
				$(this).startSlideShow();
			});
		});
	};

	var navMgr = {
		locked:false,
		navs : 'li',
		selectedClass:'selected',
		disabledClass:'disabled',
		hoverClass: 'hover',
		nextButton: null,
		previousButton : null,
		activeClass : 'active',
		contentContainer:null,
		initList : [],
		beforeDynamicLoad : function () {
			if ( this.onloadClass) {
				this.jqSelected.addClass(this.onloadClass);
			}
		},
		afterDynamicLoad : function () {
			if ( this.onloadClass) {
				this.jqSelected.removeClass(this.onloadClass);
			}
		},
		navSelection : function () {
			this.jqShowSrc = this.jqSelected;
			this.activeNavIndex = this.jqNavs.index(this.jqSelected);
			this.switchToIndex(this.activeNavIndex);
		},
		addToInitList : function () {
		    this.initList.push(function() {
				var mgr = this;
                this.jqNavs = this.jqNavContainer.find(this.navs);
				if ( this.jqNavs.length == 0 )
					$.log("can't find " + this.navs);
		        this.locked =false;
		        if ( this.nextButton ) {
		            this.jqNext = this.jqNavContainer.find(this.nextButton);
					if ( this.activeClass && this.wrapIndex )
						this.jqNext.addClass(this.activeClass);
		            this.jqNext.click(function() {
						if ( $(this).hasClass(mgr.activeClass) && !mgr.locked) {
							mgr.jqCurrent = mgr.jqNavs.filter('.' + mgr.selectedClass);
				    		mgr.activeNavIndex = mgr.jqNavs.index(mgr.jqCurrent);
							if (mgr.activeNavIndex == mgr.maxIndex )
								mgr.activeNavIndex =0;
							else
								mgr.activeNavIndex++;
							mgr.jqSelected = $(mgr.jqNavs[mgr.activeNavIndex]);
							mgr.locked = true;
							mgr.switchToIndex(mgr.activeNavIndex);
						}
					});
		        }
		        if ( this.previousButton ) {
		            this.jqPrevious = this.jqNavContainer.find(this.previousButton);
					if ( this.activeClass && this.wrapIndex )
						this.jqPrevious.addClass(this.activeClass);
		            this.jqPrevious.click(function() {
						if ( $(this).hasClass(mgr.activeClass) && !mgr.locked) {
							mgr.jqCurrent = mgr.jqNavs.filter('.' + mgr.selectedClass);
				    		mgr.activeNavIndex = mgr.jqNavs.index(mgr.jqCurrent);
							if (mgr.activeNavIndex == 0 )
								mgr.activeNavIndex =mgr.maxIndex;
							else
								mgr.activeNavIndex--;
							mgr.jqSelected = $(mgr.jqNavs[mgr.activeNavIndex]);
							mgr.locked = true;
							mgr.switchToIndex(mgr.activeNavIndex);
							//mgr.previous();
						}
					});
		        }
		        if ( this.hoverClass ) {
		            this.jqNavs.hoverClass(this.hoverClass);
		            if ( this.jqNext )
		                this.jqNext.hoverClass(this.hoverClass);
		            if ( this.jqPrevious )
		                this.jqPrevious.hoverClass(this.hoverClass);
		        }
		        var mgr = this;
		        this.display.afterHide.push(function() {
			        mgr.jqCurrent.removeClass(mgr.selectedClass);
		        });
		        this.display.afterShow.push(function() {
			        if ( mgr.jqSelected ) {
				        mgr.jqSelected.addClass(mgr.selectedClass);
				        mgr.jqSelected = null;
			        }
			        //update the next/previous if exist
			        mgr.locked = false;
		        });
			    this.jqNavs.bind('click', function(e) {
				    e.preventDefault();
            	    var trueClick = e.clientX; // add to history only if true click occured, not a triggered click
				//selected
				    mgr.jqCurrent = mgr.jqNavs.filter('.' + mgr.selectedClass);
				    mgr.activeNavIndex = mgr.jqNavs.index(mgr.jqCurrent);
					mgr.jqSelected = $(this);

				// if animation is still running, tab is selected or disabled or onClick callback returns false stop here
            	// check if onClick returns false last so that it is not executed for a disabled tab
            	    if (mgr.locked || mgr.jqSelected.is('.' + mgr.selectedClass) || mgr.jqSelected.is('.' + mgr.disabledClass) ) {
	 				    this.blur();
            		    return false;
            	    }
            	    mgr.locked = true;
				    mgr.navSelection();
			    });
				
            });
	    }
	};
	
	/*
	 * $('conatiner of tabs').navs(options)
	 */
	$.fn.navs = function(options) {
	    var settings = $.extend({},navMgr,options);
	    settings.initList = [];
	    settings.jqNavContainer = this;
		settings.addToInitList();
		var contents = $(settings.contentsContainer);
		if ( contents.length == 0 )
			$.log('unable to find nav content' + settings.contentsContainer);
		else
			contents.configureContentManager(settings);
		return this;
	};
	    
	$.fn.allowDrag = function(src,options){
		var dragMgr = null;
		var _drag = function(e) {
			e.preventDefault();
			if ( dragMgr )
				dragMgr.drag(e);
		}
		var _dragStop = function(e) {
			e.preventDefault();
			if ( dragMgr )
				dragMgr.dragStop(e);
		}
		var mleave = function(e) {
			e.preventDefault();
			if (! e.relatedTarget) {
				if ( dragMgr )
					dragMgr.dragStop(e);
			}
		}

		var defaultDragMgr = {
			sensitivity:0,
			trackMouseMove : function(e) {
			},
			drag : function(e) {
				//if ( e.which == 1 ) {
				if ( this.dragMode == 'start' ) {
					var xDelta = e.pageX - this.mX;
					var yDelta = e.pageY - this.mY;
					if ( ( Math.abs(xDelta) > dragMgr.sensitivity) || (Math.abs(yDelta)  > dragMgr.sensitivity) ) {
						this.dragMode = 'dragging';
					}
				}
				if ( this.dragMode == 'dragging' ) {
					this.trackMouseMove(e);
				}
				/*} else {
					this.dragStop(e);
				}*/
			},
			dragStop : function (e) {
				if ( this.dragMode ) {
					$(document).unbind('mousemove',_drag).unbind('mouseup',_dragStop).unbind('mouseout',mleave);
					dragMgr = null;
					this.dragMode = null;
				}
			}
		};
		var content = this;
		$(src,this).bind('mousedown',function (e) { 
			if ( dragMgr == null || !dragMgr.dragMode ) {
			    e.preventDefault();
				dragMgr =$.extend({},defaultDragMgr, options);
				dragMgr.mX = dragMgr.oX = e.pageX;
				dragMgr.mY = dragMgr.oY = e.pageY;
				dragMgr.offset = content.position();

				dragMgr.dragMode='start';
				$(document).bind('mouseout',mleave).bind('mouseup',_dragStop).bind('mousemove',_drag);
			}
		}).css({cursor:'move'});
		
		return this;
		
	};

	/*
 	 * Layer object for popup menu, tooltip, dialog (modal/none modal)
 	 * shimlayer is needed only for <= IE6
	 * shimlayer sizes modal dialog: full window size; none-modal, tooltip, popup: size of container
 	 * zIndex 1000 *n reserve for shim layer
 	 * zIndex 1000 * n + 1 reserver for modal overlay
 	 * zIndex 1000 * n  + 2 reserve for each container 
 	 */	
	var _needShimLayer = ($.browser.msie && ($.browser.version < 7));
	$.layerMgr = {
			_layers : [],
			newLayer : function( content,options ) {
				var defaultLayer = {
					cloneData : false,
					onOpen : null,
					onClose : null,
					onOpenEvents : [],
					onCloseEvents : [],
					onInit : function() {},
					addOnOpenEvent : function (f) {
						this.onOpenEvents.push(f);
					},
					open: function (external) {
						if (!external && $.isFunction(this.onOpen)) {
							// execute the onOpen callback 
					        this.onOpen.apply(this);
						}
						else {
							if ( this.cloneData ) {
					            this.jqClonedContent = this.jqContent.clone().appendTo('body');
							}
							if ( this.jqShim )
								this.jqShim.show();
							if ( this.jqOverlay )
								//this.overlay.show();
								this.jqOverlay.fadeIn('slow');
							this.jqContent.show();
							//this.container.slideDown('slow');
						}
						// bind default events
						this.bindEvents();
					},
					close: function (external) {
						//call close on all layers with higher index than the current index
						$.layerMgr._layers.pop();
						if ($.isFunction(this.onClose) && !external) {
							// execute the onClose callback
							this.onClose.apply(this);
						}
						else {
						    for(var i=0; i < this.onCloseEvents.length; i++ ){
							    this.onCloseEvents[i].apply(this);
						    }
							this.jqContent.hide();
							if ( this.cloneData ) {
							    this.jqContent.remove();
								this.jqContent = this.jqClonedContent;
							}
							if ( this.jqOverlay )
								this.jqOverlay.hide();
								//this.jqOverlay.fadeOut('slow');
							if (this.jqShim) {
								if ( this.jqShim == this._modalShimLayer )
									this.jqShim.hide();
								else
									this.jqShim.remove();
							}
						    this.unbindEvents();
						    if ( this.src ) {
							    this.src._layer = null;
							    this.src = null;
						    }
						}
					},
					trackMouseMove :function( e ) {
						var xDelta = e.pageX - this.mX;
						var yDelta = e.pageY - this.mY;
						if ( ( Math.abs(xDelta) > this.sensitivity) || (Math.abs(yDelta)  > this.sensitivity) ) {
							var offset = this.jqContent.position();
							this._moveTo((offset.left + xDelta),(offset.top + yDelta));
							this.mX = e.pageX;
							this.mY = e.pageY;
						}

					},
					bindEvents: function () {
						for(var i=this.onOpenEvents.length-1; i >= 0; i-- )
							this.onOpenEvents[i].apply(this);
					},
					unbindEvents: function () {
					},
					createShimLayer : function() {
						if ( _needShimLayer )
							return $('<iframe src="javascript:false;">')
								.css({
									opacity: 0, 
									position: 'absolute',
									height: '100%',
									width: '100%',
									top: 0,
									left: 0
								})
								.hide()
								.appendTo('body');
						return null;
					},
					_moveTo : function ( left, top ) {
						var css = {position:'absolute', top:top+'px', left:left+'px'};
						if ( this.jqShim )
							this.jqShim.css(css);
						this.jqContent.css(css);
						//alert(this.jqContent.html());
					},
					createOverlay : function () { return null; }

				};
		
				function setZindex(layer, index ) {
					index = (index + 1) * 1000;
					if ( layer.jqShim )
						layer.jqShim.css({zIndex : index});
					++index;
					if ( layer.jqOverlay )
						layer.jqOverlay.css({zIndex : index, opacity : .5});
					++index;
					layer.jqContent.css({zIndex : index});
				}
				function initLayer (layer,content) {
					layer.layers = $.layerMgr._layers;
					layer.layers.push(layer);
					var index = layer.layers.length;
					layer.index = index;
					layer.jqShim = layer.createShimLayer();
					layer.jqOverlay = layer.createOverlay();
					layer.jqContent = $(content);
					layer.onInit();
					setZindex(layer,index);
				};
				var layer = $.extend({}, defaultLayer, options);
				initLayer(layer,content);
				return layer;
			}
		};
		
	jQuery.extendLayer = function(defaultOpts,options) {
		var opts =$.extend({}, defaultOpts, options);
        opts.onOpenEvents = defaultOpts.onOpenEvents ? [].concat(defaultOpts.onOpenEvents): [];
		if ( options && options.onOpenEvents )
			opts.onOpenEvents = opts.onOpenEvents.concat(options.onOpenEvents );
        opts.onCloseEvents = defaultOpts.onCloseEvents ? [].concat(defaultOpts.onCloseEvents): [];
		if ( options && options.onCloseEvents )
			opts.onCloseEvents = opts.onCloseEvents.concat(options.onCloseEvents );
		return opts;
	};
	function fitHorizontal(x,w) {
	    x -= $(document).scrollLeft(); 
	    return x >= 0  && $(window).width()>= (x + w); 
    }
	function fitVertical(y,h) {
	    y -= $(document).scrollTop(); 
	    return y >= 0 && $(window).height()>= (y + h); 
    }

	/*
	 * $(content).popupLayer(eventSrc,options)
	 */
	$.fn.popupLayer = function(src,options) {
		var defaultPopuLayer = {
			positionBy : 'source',
			//source ref - left is same as bottomLeft
			positionRef : 'bottomLeft',
			targetRef : 'topLeft',
			pointerLength : 0,
			sourceMovable : false,
			xOffset : 0,
			yOffset : 0,
			beforeOpenPopup : function () {},
			targetLeftSrcLeftX : function(srcX,srcW,popupW){
				this.srcHorPos = 'left';
			    var x = srcX + this.xOffset;
			    if ( fitHorizontal(x,popupW) ) return x;
                var x2 = srcX + srcW - popupW - this.xOffset;
			    if ( fitHorizontal(x2,popupW) ) {this.srcHorPos = 'right';return x2;}
	            return x; 
			},			
			targetLeftSrcRightX : function(srcX,srcW,popupW){
				this.srcHorPos = 'left';
			    var x = srcX + srcW + this.xOffset;
			    if ( fitHorizontal(x,popupW) ) return x;
			    //try aligning right
			    var x2 = srcX + srcW - popupW - this.xOffset;
			    if ( fitHorizontal(x2,popupW) ) {this.srcHorPos = 'right';return x2;}
	            return x; 
			},			
			targetRightSrcLeftX : function(srcX,srcW,popupW){
				this.srcHorPos = 'right';
			    var x = srcX - popupW + this.xOffset;
			    if ( fitHorizontal(x,popupW) ) return x;
			    //try aligning right
			    var x2 = srcX - this.xOffset;
			    if ( fitHorizontal(x2,popupW) ) {this.srcHorPos = 'left';return x2;}
			    //align to the edge of the window
	            return x; 
			},			
			targetRightSrcRightX : function(srcX,srcW,popupW){
				this.srcHorPos = 'right';
			    var x = srcX + srcW - popupW + this.xOffset;
			    if ( fitHorizontal(x,popupW) ) return x;
			    //try aligning left
			    var x2 = srcX - this.xOffset;
			    if ( fitHorizontal(x2,popupW) ) {this.srcHorPos = 'left';return x2;}
	            return x; 
			},			
			targetTopSrcTopY : function(srcY,srcH,popupH){
				this.srcVerPos = 'top';
			    var y = srcY + this.pointerLength + this.yOffset;
			    if ( fitVertical(y,popupH) ) return y;
			    //try aligning top
			    var y2 = srcY - popupH - this.pointerLength - this.yOffset;
			    if ( fitVertical(y2,popupH) ) {this.srcVerPos = 'bottom';return y2;};
	            return y; 
			},			
			targetTopSrcBottomY : function(srcY,srcH,popupH){
				this.srcVerPos = 'top';
			    var y = srcY + srcH + this.pointerLength + this.yOffset;
			    if ( fitVertical(y,popupH) ) return y;
			    var y2 = srcY - popupH - this.pointerLength - this.yOffset;
			    if ( fitVertical(y2,popupH) ) {this.srcVerPos = 'bottom';return y2;}
	            return y; 
			},			
			targetBottomSrcTopY : function(srcY,srcH,popupH){
				this.srcVerPos = 'bottom';
			    var y = srcY -popupH - this.pointerLength + this.yOffset;
			    if ( fitVertical(y,popupH) ) return y;
			    //try aligning bottom
			    var y2= srcY + srcH + this.pointerLength - this.yOffset;
			    if ( fitVertical(y2,popupH) ) {this.srcVerPos = 'top';return y2;};
				return y;
			},			
			targetBottomSrcBottomY : function(srcY,srcH,popupH){
				this.srcVerPos = 'bottom';
			    var y = srcY + srcH -popupH - this.pointerLength + this.yOffset;
			    if ( fitVertical(y,popupH) )return y;
			    var y2 = srcY + srcH + + this.pointerLength - this.yOffset;
			    if ( fitVertical(y2,popupH) ){this.srcVerPos = 'top';return y2;};
	            return y; 
			},			
			calculateX : function(srcX,srcW,popupW,srcAlign,targetAlign){
			    if ( targetAlign == 'left' ) {
			        if ( srcAlign == 'left' ) {
			            return this.targetLeftSrcLeftX(srcX,srcW,popupW);
			        } else {
			            return this.targetLeftSrcRightX(srcX,srcW,popupW);
			        }
			    } else {
			        if ( srcAlign == 'left' ) {
			            return this.targetRightSrcLeftX(srcX,srcW,popupW);
			        } else {
			            return this.targetRightSrcRightX(srcX,srcW,popupW);
			        }
			    }
			},
			calculateY : function(srcY,srcH,popupH,srcAlign,targetAlign){
				//alert(srcAlign + ":" + targetAlign);
			    if ( targetAlign == 'top' ) {
			        if ( srcAlign == 'top' ) {
			            return this.targetTopSrcTopY(srcY,srcH,popupH);
			        } else {
			            return this.targetTopSrcBottomY(srcY,srcH,popupH);
			        }
			    } else {
			        if ( srcAlign == 'top' ) {
			            return this.targetBottomSrcTopY(srcY,srcH,popupH);
			        } else {
			            return this.targetBottomSrcBottomY(srcY,srcH,popupH);
			        }
			    }
			},
			openPopup : function ( src ) {
				this.src = src;
				this.beforeOpenPopup();
				if ( this.sourceMovable ) {
				    this.jqSrcContainer = $(this.src).parent();
				    this.jqSrcContainer.css({position:'relative'});
				    this.jqContent.remove().css({position:'absolute'});
				    this.jqSrcContainer.append(this.jqContent);
				    if ( this.jqShim ){
				        this.jqShim.remove().appendTo(this.jqSrcContainer);
				    }
			    } 
			    
			    //if ( this.jqContent.parent().length == 0 )
			    //    this.jqContent.appendTo('body');
				src._layer = this;
				//quickly show the container and its content so that browser can 
				// calculate actual width and height
				this.jqContent.show();
				var w = this.jqContent.outerWidth();
				var h = this.jqContent.outerHeight();
				this.left=0;
				this.top = 0;
				this.offset(src,w,h);
				this.jqContent.hide();
				this._sizeTo(w,h);
				this._moveTo(this.left,this.top);
				this.open();
			},
			offset : function(src,w,h) {
					var jqSrc = $(src);
					if ( this.positionBy == 'source' ) {
						if ( this.positionRef == 'left' ) this.positionRef = 'topLeft';
						this.verPos =this.positionRef == 'topRight' ||this.positionRef == 'topLeft' ? 'top' : 'bottom'; 
						this.horPos = this.positionRef == 'bottomLeft' ||this.positionRef == 'topLeft' ? 'left' : 'right';
						//alert(this.positionRef + "===" + this.targetRef);
						var offset = jqSrc.offset();
						this.left = this.calculateX(offset.left,jqSrc.outerWidth(),w,this.horPos,this.targetRef == 'bottomLeft' || this.targetRef == 'topLeft' ? 'left' : 'right');
						this.top = this.calculateY(offset.top,jqSrc.outerHeight(),h,this.verPos,this.targetRef == 'topRight' ||this.targetRef == 'topLeft' ? 'top' : 'bottom');
						if ( this.pointerLength > 0 ) {
							this.positionClass = '.' + this.srcVerPos + '-' + this.srcHorPos + '-arrow';;
							$(this.positionClass,this.jqContent).show();
						}
						if ( this.sourceMovable ) {
							offset = this.jqContent.parent().offset();
							this.left -= offset.left;
							this.top -= offset.top;
						}
					} else {
						this.left = this.mX + this.xOffset;
						this.top = this.mY + this.yOffset;
					}
				},
			_sizeTo : function ( w, h ) {
				if ( this.jqShim ) {
					var css = {width:w+'px', height:h+'px'};
					this.jqShim.css(css);
				}
			}
		};
		var opts = $.extend({}, defaultPopuLayer, options);
		var popup = $.layerMgr.newLayer( this,opts );
		popup.openPopup(src);
		return this;
	};
	
	/*
	 * $(content).popup(eventSrc,options)
	 */
	var _singlePopupop = null;
	$.fn.popup = function (eventSrc,options) {
		var closePopup = function () {
		    if ( _singlePopupop ) {
		        _singlePopupop.close();
                _singlePopupop = null;
		    }
		}
		closePopup();
	    var defaultPopup = {
			hooverPopup : false,
		    closeOnClick : true,
			onOpenEvents : [
				function () {
		            _singlePopupop = this;
		            if ( this.closeOnClick )
		                $(document).bind('click',closePopup);
					if ( this.hooverPopup ) {
						//set delay on mouseleave
						this.jqContent.bind("mouseleave", closePopup);
					}

			}],
			onCloseEvents : [
				function () {
		        if ( this.closeOnClick )
		            $(document).unbind('click',closePopup);
				if ( this.hooverPopup ) {
				    this.jqContent.unbind("mouseleave", closePopup);
				}
		         _singlePopupop = null;
			}]

		};
		var opts = $.extendLayer(defaultPopup,options);
		$(this).popupLayer(eventSrc,opts);
		return this;
	};

	/*
	 * $(eventSrcs).attachHoverPopup(content,options)
	 */
	$.fn.attachPopup = function(content,startevent,options) {
		// default configuration options
		var defaultPopup = {
			delay: 150,
			sensitivity: 5,
			hooverPopup : true,
			onCloseEvents : [
				function () {
				cleanPopup(this.src);
			}],
			onOpenEvents : [
				function () {
					var popup = this;
					var src = this.src;
					this.jqContent.bind("click", function(e) {
						popup.close();
					})
					.bind("mouseenter", function(e) {
						cleanPopup(src);
					})
					.bind("mouseleave", function(e) {
						//close popup but delay it just in case user move back to the src that trigger
						//of this popup
						hidePopup(src,'container mouseleave');
					});
					$('.closeBtn',popup.jqContent).bind('click',function (e) {
				    	popup.close();
			        });

				}]
		};
		var options = $.extendLayer(defaultPopup,options);
		
		var showPopup = function (content,src,opts) {
			cleanPopup(src);
			$(content).popup(src,opts);
		};
		var hidePopup = function(src,tag) {
			if ( src._layer )
				src._hoverPopup_t = setTimeout(function() { if( src._hoverPopup_t && src._layer)src._layer.close();src._hoverPopup_t=null;},options.delay);
		};
		var cleanPopup = function(src) {
			if (src && src._hoverPopup_t) { clearTimeout(src._hoverPopup_t); src._hoverPopup_t=null;}
		};
		var jqContent = $(content);
		var events;
		if ( options.positionBy == 'mouse') {
			events = ' mousemove mouseleave';
		} else {
			events = ' mouseleave';
		}
		events = startevent + events;
		return this.each(function(){
			var src = this;
			$(src).bind(events,function(e) {
				// next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
				var p = (e.type == "mouseenter" ? e.fromElement : e.toElement) || e.relatedTarget;
				while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } }
				if ( p == this ) { return false; }

				// copy objects to be passed into t (required for event object to be passed in IE)
				var ev = jQuery.extend({},e);

				// else e.type == "onmouseover"
				if (e.type == "mousemove") {
					if ( src._layer ) {
						//move to new location
						var xDelta = e.pageX - src._layer.mX;
						var yDelta = e.pageY - src._layer.mY;
						if ( ( Math.abs(xDelta) > options.sensitivity) || (Math.abs(yDelta)  > options.sensitivity) ) {
							var offset = src._layer.jqContent.position();
							src._layer._moveTo((offset.left + xDelta),(offset.top + yDelta));
							src._layer.mX = e.pageX;
							src._layer.mY = e.pageY;
						}

					}
				} else if (e.type == "mouseenter" || e.type == "click") {
					if ( src._layer ) {
						//popup already opend, clear the timer of the 
						//layer so that it does not close the layer
						cleanPopup(src);
					} else {
						//delay opening of popup
						options.mX = e.pageX;
						options.mY = e.pageY;
						src._hoverPopup_t = setTimeout(function() { showPopup(content,src,options);},options.delay);
					}

				} else {
					if ( src._layer ) {
						hidePopup(src,'src ml');
					} else {
						cleanPopup(src);
					}
				}
				return this;
			});
		});
	};

	/*
	 * $(eventSrcs).attachHoverPopup(content,options)
	 */
	$.fn.attachHoverPopup = function(content,options) {
	    this.attachPopup(content,"mouseenter",options);
	    return this;
	};

	var defaultDialog = {
		center: true,
		draggable: true,
		sensitivity:1,
		onOpenEvents : [
			function () {
				var popup = this;
				$('.close',popup.jqContent).click(function (e) {
					e.preventDefault();
					popup.close();
				});
				if ( popup.center ) {
			        var w = popup.jqContent.outerWidth();
			        var h = popup.jqContent.outerHeight();
			        var top = ($(window).height() -h )/2 + $(document).scrollTop();
			        top = Math.max(top,0);
			        var left = ($(window).width() -w )/2 + $(document).scrollLeft();
			        left = Math.max(left,0);
			        if ( this.jqShim)
				        this.jqShim.css({position:'absolute',top: top + 'px',left: left + 'px',width:w + 'px', height:h + 'px'});
			        this.jqContent.css({top:top + 'px', left:left + 'px'});
		        }

				var dragOpts = {popup:this,
					trackMouseMove :function( e ) {
					    var pX = e.pageX;
					    var pY = e.pageY;
						var xDelta = pX - this.mX;
						var yDelta = pY - this.mY;
						if ( ( Math.abs(xDelta) > this.sensitivity) || (Math.abs(yDelta)  > this.sensitivity) ) {
						    xDelta = pX - this.oX;
						    yDelta = pY - this.oY;
						    var w = this.popup.jqContent.width();
						    var h = this.popup.jqContent.height();
						    var left = this.offset.left + xDelta;
						    var dW = $(document).width() - 5; 
						    if ( left + w >= dW )
						        left = dW - w;
						    if ( left < 0 )
						        left = 0;
						    var top = this.offset.top + yDelta;
						    var dH = $(document).height() - 5;
						    if ( top + h >= dH )
						        top = dH - h;
						    if ( top < 0 )
						        top = 0;
							this.popup._moveTo(left,top);
							this.mX = e.pageX;
							this.mY = e.pageY;
						}

					}
				};
				popup.jqContent.allowDrag('.dialogHeading',dragOpts);

			}]
			
	};
	$.fn.dialog = function (options) {
		var opts = $.extendLayer(defaultDialog,options);
		$(this).css({left:'-1000px'}).show();
		var h = $(this).outerHeight();
		$(this).css({height: h + 'px'}).hide();
		var dialog = $.layerMgr.newLayer( this,opts );
		dialog.open();
		return this;
	};
	
	
	/*
	 * $(content).modal(options)
	 */
	var defaultModal = {
		center: true,
		draggable: false,
		_modalOverlay : null,
		_modalShimLayer : null,
		createOverlay : function () { return this._modalOverlay; },
		createShimLayer : function() { return this._modalShimLayer; },
		onOpenEvents : [
			function () {
				var popup = this;
				$('.close',popup.jqContent).click(function (e) {
					e.preventDefault();
					popup.close();
				});
		        if ( this.center ) {
			        var w = this.jqContent.outerWidth();
			        var h = this.jqContent.outerHeight();
				    if ($.browser.msie ) {
				        if ( ($.browser.version < 7)) {
					        var wHeight = $(document.body).height() + 'px';
					        var wWidth = $(document.body).width() + 'px';
					        this._modalOverlay.css({position: 'absolute', height: wHeight});
			                this._modalShimLayer.css({width:w + 'px', height:h + 'px',marginLeft:'-' + (w/2) + 'px',marginTop: '-' + (h/2) + 'px'});
					    }
					    this.jqContent.css({position: 'absolute'});
				    }		
				    this.jqContent.css({marginLeft:'-' + (w/2) + 'px',marginTop: '-' + (h/2) + 'px'});
			    }

			}]
			
	};
	var _modalDialog = null;
	$.fn.modal = function (options) {
		if ( defaultModal._modalOverlay == null ) {
			defaultModal._modalOverlay = $('<div>').attr('id', 'modalOverlay').appendTo('body');
			if (_needShimLayer) {
				defaultModal._modalShimLayer = $('<iframe class="modalShim" src="javascript:false;">')
						.css({opacity: 0, overflow:'auto'})
						.hide()
						.appendTo('body');
			}

		}
		
		var opts = $.extendLayer(defaultModal,options);
		
		if ( opts.center ) {
			var w = $(this).outerWidth();
			var h = $(this).outerHeight();
			if ( opts.draggable ) {
				/*opts.bindEvents = function () {
					var popup = this;
					$('.closeBtn',popup.jqContent).click(function (e) {
					e.preventDefault();
					popup.close();
				};*/

			} else {

			}
		}
		_modalDialog = $.layerMgr.newLayer( this,opts );
		_modalDialog.open();
		return this;
	};
    jQuery.closeModalDialog = function () {
        _modalDialog.close();
    };

	$.fn.configureDynamicLoadModalDialog = function(options) {
		var opts = $.extendLayer({showModal : function() {$(this.content).modal()}},options);
		this.click( function(e) {
			var content = $(opts.content);
			if ( content.length == 0 ) {
				$('body').loadContent(opts.url,null,function() {opts.onLoad();opts.showModal();},null);
			} else {
				opts.showModal();
			}
			e.preventDefault();
		});
	}
    var defaultBubbleHelp = {
	        width:'320px',
  			delay: 350,
  			className : 'help-tip',
			positionRef : 'topRight',
			targetRef : 'bottomLeft',
			xOffset : -20,
  			pointerLength : 14, 
			onOpenEvents : [
				function () {
 			    	var popup = this;
			    	$('.closeBtn',popup.jqContent).click(function (e) {
				    	//e.preventDefault();
				    	popup.close();
			        });
				}],
            onCloseEvents : [
                function () {
                    if ( this.positionClass )
				        $(this.positionClass).hide();
                    this.container.remove();
		        }],
		    xoffset : function(src,w,h) {
				var jqSrc = $(src);
				var sw = jqSrc.outerWidth();
			    var sh = jqSrc.outerHeight();

    			var offset = jqSrc.offset();
    			var horPos = 'right';
    			var verPos = 'bottom';
				var left = offset.left + (sw/2) + this.xOffset;
		        if ($(window).width()-(left -16 - $(document).scrollLeft())> w) {
		            horPos = 'left';
		            this.left = left - 16;
		        } else {
		            this.left = left-w+ (sw/2) + 9 + this.xOffset;
		            horPos = 'right';
		        }
    			var top = offset.top + this.yOffset;
				if ( $(window).height()-(top + 32 -$(document).scrollTop()+sh)> h) {
				    this.top = top + 32;
				    verPos = 'top';
				} else {
				    this.top = top - h - 9;
				    verPost = 'bottom';
				}
				

				this.positionClass = '.' + verPos + '-' + horPos + '-arrow';;
				$(this.positionClass,this.jqContent).show();
				

			},
            container : null
    };
	
	jQuery.extendBubbleHelp = function(options) {
		options = $.extendLayer(defaultBubbleHelp,options);
	    options.container =
 	        	$('<div class="' + options.className + '"><table border="0" cellpadding="0" cellspacing="0" width="100%">' +
				'<tr><td class="help-tip-rtl round-top-left">&nbsp;</td><td class="help-tip-rtm round-top-middle">&nbsp;</td><td class="help-tip-rtr round-top-right">&nbsp;</td></tr>' +
				'<tr><td class="help-tip-rml round-middle-left">&nbsp;</td><td class="help-tip-rm round-middle">' +		
				'<table style="float: left; display: inline;" border="0" cellpadding="0" cellspacing="0" width="100%">' +
				'<tr><td align="left" valign="top" width="100%"><div class="popText"></div></td>' +
				'<td style="padding-left: 3px;" valign="top" width="19px"><div class="closeBtn"></div></td></tr></table>' +
				'</td><td class="help-tip-rmr round-middle-right">&nbsp;</td></tr>' +
				'<tr><td class="help-tip-rbl round-bottom-left">&nbsp;</td><td class="help-tip-rbm round-bottom-middle" width="100%">&nbsp;</td><td class="help-tip-rbr round-bottom-right">&nbsp;</td></tr></table>' +
				'<div class="top-left-arrow">&nbsp;</div><div class="top-right-arrow">&nbsp;</div><div class="bottom-left-arrow">&nbsp;</div><div class="bottom-right-arrow">&nbsp;</div></div>').hide();
        return options;
    };
	
	$.fn.attachHoverBubbleHelp = function(content,options) {
		var opts = $.extendBubbleHelp(options);
		opts.beforeOpenPopup = function() {
			$('.popText',opts.container).html(content);
			opts.container.css({width:opts.width}).appendTo('body');
		}
 	    this.each(function() { $(this).attachHoverPopup(opts.container[0],opts)});
    };
 	$.fn.attachStaticBubbleHelp = function(content,options) {
		var opts = $.extendBubbleHelp(options);
		opts.closeOnClick =false;
		opts.beforeOpenPopup = function() {
			$('.popText',this.container).html(content);
			this.container.css({width:opts.width}).appendTo('body');
		}
        opts.container.popup(this,opts);
		return this;
    };
   

	var fieldHelpPopup = null;    
	$.fn.inputFields = function(options) {
		options = {className :'tipField', charCountClass:'charCount'};
		if( options.className ) {
			$(window).unload(function() {$('.' + options.className).val('');});
		    $('form').submit(function() {$(this).find('.' + options.className).val('');});
		}
		this.each(function() {
    		var $this = $(this);
			var fieldTip = $this.attr('title');
			if ( fieldTip) {
      			if ($.browser.msie && $this.val() == fieldTip) {
        			$this.val('');
      			}
				if ($this.val() == '') {
        			$this.addClass(options.className);
					$this.val(fieldTip);
				}
			}

    		var keycount = function(i) {
      			var max = $(this).attr('maxlength');
      			var val = $(this).attr('value');
      			var cur = 0;
      			if(val)
        			cur = val.length;
      			var left = max-cur;
      			var c = $(this).next("span").find(".counter");
      			c.text(left.toString());
      			if(left <= 10)
          			c.css("background","#F4F379");
      			else
          			c.css("background","none");
    		};
      		$this.focus(function() {
				var $$this = $(this);
        		if ($$this.is('.' + options.className)) {
          			$$this.val('').removeClass(options.className);
        		}
				if ( fieldHelpPopup ) {
					fieldHelpPopup.close();
					fieldHelpPopup = null;
				}
				var fieldHelp = $$this.attr('fieldHelp');
				if ( fieldHelp ) {
					fieldHelpPopup = $.extendBubbleHelp({});
					fieldHelpPopup.closeOnClick =false;
                    fieldHelpPopup.sourceMovable = true;
					fieldHelpPopup.beforeOpenPopup = function() {
						$('.popText',this.container).html(fieldHelp);
						this.container.css({width:'300px'});
					};
					fieldHelpPopup.container.popup(this,fieldHelpPopup);
					fieldHelpPopup = this._layer;
				}
				if ($$this.is('.' + options.charCountClass)) {
    				var max = $$this.attr('maxlength');
					if ( max ) {
    					var val = $$this.val();
    					var cur = 0;
    					if(val) // value="", or no value at all will cause an error
      						cur = val.length;
    					var left = max-cur;
    					$$this.after("<span><span class='counter'>"+ left.toString()+"</span> characters remaining</span>");
    					// Style as desired
    					var c = $$this.next("span").find(".counter");
    					c.css("margin-left","10px");
    					c.css("padding", "0 3px 0 3px")
    					c.css("border", "1px solid #ccc")
    					if(left <= 10)
        					c.css("background","#F4F379");
    					else
        					c.css("background","none");
						$$this.keyup(keycount);

					}

				}
      		});
    
      		$this.blur(function() {
				if ( fieldHelpPopup ) {
					fieldHelpPopup.close();
					fieldHelpPopup = null;
				}
				var $$this = $(this);
        		if ($$this.val() == '') {
          			$$this.addClass(options.className);
          			$$this.val(fieldTip);
				}
				if ($$this.is('.' + options.charCountClass)) {
					$$this.next('span').remove();
				}
 			});
			//return this;
  		});
  		return this;

	};
    var MonthDays = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
    function GetDaysCountForMonth(SomeYear, SomeMonth) {
        return ((SomeMonth == 1) && ((SomeYear % 400 == 0) || ((SomeYear % 4 == 0) && (SomeYear % 100 != 0)))) ? 29 : MonthDays[SomeMonth];
    }	
	var defaultCalendar = {
	  	    setCalendarContent:function(y,m) {
	  	        var calPopup = this;
		        var nextMonthName = MonthNames[(m < 11 ? m+1 :0)];
		        var monthName = MonthNames[m];
		        var prevMonthName = MonthNames[(m > 0 ? m -1 :11)];
		        var dt = new Date(y, m, 1);
		        this.firstDay = dt.getDay();
		        this.dayCount = GetDaysCountForMonth(y,m);
		        this.displayedYear = y;
		        this.displayedMonth = m;

		        var HTML = '<table class="calendar" cellspacing="0" cellpadding="1"><tr class="caltitle"><td>';
		        if ( y > this.minYear || m > 0 ) {
			        HTML += '<a id="calPrev" href="#"><img src="' + PrevURL + '" title="' + prevMonthName + '" border="0"></a>';
		        } else {
			        HTML += '&nbsp;';
		        }
		        HTML += '</td><td nowrap align="center" colspan="5">' + monthName + '&nbsp;' + y + '</td><td>';
		        if ( y < this.maxYear || m < 11 ) {
        	        HTML += '<a id="calNext" href="#"><img src="' + NextURL + '" title="' + nextMonthName + '" border="0"></a>';
                } else {
			        HTML += '&nbsp;';
                }
                HTML += '</td></tr><tr>';
                for (var w=0;w<7;w++) 
         	        HTML += '<td class="calhd">' + WeekDays[w] + '</td>';
		        HTML += '</tr>';
		        var sameMonthAndYear = this.displayedYear == this.valueYear && this.displayedMonth == this.valueMonth;
		        var todayMonthAndYear = this.displayedYear == this.todayYear && this.displayedMonth == this.todayMonth;
   	   	        for (var j=0;j< 6;j++) {
      		        HTML += '<tr>';
      	   	        for (var i=1;i<=7;i++) {
         		        var Day = (j * 7) + (i - this.firstDay);
         		        if ((Day >= 1) && (Day <= this.dayCount)) {
					        var cls = 'calcell ';
            		        if ( sameMonthAndYear && (Day == this.valueDay)) {
			   			        cls += "calseldate";
            		        }
            		        if ( todayMonthAndYear && (Day == this.todayDay)){
							    cls += "caltoday";
            		        }	
            		        HTML += '<td align="center" class="' + cls + '">' + Day + '</td>';
         		        }
         		        else HTML += '<td>&nbsp;</td>'; 
      		        }
      		        HTML += '</tr>';
   		        }
   		        HTML += '</table>';
                this.calendarPopup = $('#CalendarPopup');
                if ( this.calendarPopup.length == 0 ) {
                    $('<div id="CalendarPopup" class="popupWindow"></div>').appendTo('body');
                    this.calendarPopup = $('#CalendarPopup');
                }
		        this.calendarPopup.html(HTML);
		        this.calendarPopup.find('#calPrev').click(function(e){calPopup.previous();return false;});
		        this.calendarPopup.find('#calNext').click(function(e){calPopup.next();return false;});
		        this.calendarPopup.find('.calcell').hoverClass('calhover').click(function(e){calPopup.select(this);return false;});
	            $(this.yearElement).bind('change',function(e){calPopup.yearChanged();}); 
	            $(this.monthElement).bind('change',function(e){calPopup.monthChanged();}); 

	        },
	        next : function() {
		        var m = this.displayedMonth;
		        var y = this.displayedYear;
		        if ( m < 11 ) {
		            m++;
		        } else {
			        m = 0;
			        y++;
		        }
		        this.setCalendarContent(y,m);
	        },
	        previous : function() {
		        var m = this.displayedMonth;
		        var y = this.displayedYear;
		        if ( m > 0 ) {
			        m--;
		        } else {
			        m = 11;
			        y--;
		        }
		        this.setCalendarContent(y,m);
	        },
	        select : function(src) {
	            //set the year to be the same as the calendar year
		        for(var i = 0;i<this.yearElement.options.length;++i){
			        if(this.yearElement.options[i].value == this.displayedYear){
				        this.yearElement.selectedIndex = i;
				        break;
			        }
		        }
		
		        var m = "" + this.displayedMonth;
		        for(var i = 0;i<this.monthElement.options.length;++i){
			        if(this.monthElement.options[i].value == m){
				        this.monthElement.selectedIndex = i;
				        break;
			        }
		        }
		        this.monthChanged();
		        var day = $(src).html().trim();
		        for(var i = 0;i<this.dayElement.options.length;++i){
			        if(this.dayElement.options[i].value == day){
				        this.dayElement.selectedIndex = i;
				        break;
			        }   
		        }
                this.close();
		
	        },	
	        yearChanged : function (elm) {
		        this.monthChanged(elm);
	        },
	        monthChanged : function (elm) {
		        if ( this.monthElement.options[this.monthElement.selectedIndex].value != '' && 
			        this.yearElement.options[this.yearElement.selectedIndex].value != '' ) {
			        this.setCurrentValues();
			        var newDays = GetDaysCountForMonth(this.valueYear,this.valueMonth);
			        var dayList = this.dayElement;
			        var dayInc = 1;
			        if ( dayList.options[0].value == '') {
			            dayInc = 0;
			            newDays++;
			        }
			        if ( newDays != dayList.length ) {
				        var oldSize = dayList.length;
				        for (var k=Math.min(newDays,oldSize);k<Math.max(newDays,oldSize);k++) {
					            (k >= newDays) ? dayList.options[newDays] = null : dayList.options[k] = new Option(dayInc + k, dayInc + k);
				        }
				        var dayPick = Math.min(this.valueDay, newDays);
				        if ( dayList.options[0].value != '')
					        dayPick--;
				        if ( dayPick >= dayList.length)
				            dayPick = dayList.length-1;
				        dayList.options[dayPick].selected = true;
			        }
		        }	
    	    },
	        setCurrentValues : function(t) {
		        var Today = new Date();
		        var yr = this.yearElement.options[this.yearElement.selectedIndex].value;
		        if ( yr == '' )
			        yr = this.yearElement.options[1].value;
		        this.valueYear = parseInt(yr,10);
		        if ( this.monthElement.options.length > 12 ) {
			        this.valueMonth = this.monthElement.selectedIndex > 0 ? this.monthElement.selectedIndex - 1 : Today.getMonth();
		        } else {
			        this.valueMonth = this.monthElement.selectedIndex;
		        }
		        if ( this.dayElement.options[0].value == '') {
			        this.valueDay = this.dayElement.selectedIndex > 0 ? this.dayElement.selectedIndex : Today.getDate();
		        } else {
			        this.valueDay = this.dayElement.selectedIndex + 1;
		        }
	        },
	        onOpen : function () {
		        this.setCurrentValues();
	            this.setCalendarContent(this.valueYear,this.valueMonth);
	            this.open(true);
	        }

	    };    	
	$.fn.calendar = function() {
        this.each(function() {
	        var settings = $.extend({},defaultCalendar);
		    settings.name = $(this).attr('id');  
	        settings.dayElement = $('#' + settings.name +'Day')[0];
	        settings.monthElement = $('#' + settings.name +'Month')[0];
	        settings.yearElement =  $('#' + settings.name +'Year')[0];
	        var yr = settings.yearElement.options[0].value;
	        if ( yr == "" )
	            yr = settings.yearElement.options[1].value;
	        settings.minYear = parseInt(yr,10);
	            //alert(settings.minYear);
	        yr = settings.yearElement.options[settings.yearElement.length-1].value;
	        settings.maxYear = parseInt(yr,10);
		    settings.monthChanged(settings.monthElement);
		    var Today = new Date();
		    settings.todayYear = Today.getFullYear();
		    settings.todayMonth = Today.getMonth();
		    settings.todayDay = Today.getDate();
		    settings.setCurrentValues();
		    settings.setCalendarContent(settings.valueYear,settings.valueMonth);
		    $(this).show().attachPopup(settings.calendarPopup,"click",settings);

	    });
	    return this;
    };
	
})(jQuery);

var favorites = function() {
		this.domain = 'kijiji.com'; // default value
		this.panelDisplayed = true;
		
		function setDomain(newDomain) {
			this.domain = newDomain;
		}
		
		function setPanelDisplayed(newPanelDisplayed) {
			this.panelDisplayed = newPanelDisplayed;
		}
		
		function getPanelDisplayed() {
			return this.panelDisplayed;
		}
		
		function positionPanel(){
			var panelHeight = $("#myFavorites-panel").outerHeight(true);;
			var panelWidth =$("#myFavorites-panel").outerWidth(true);
			var topPosition = document["documentElement"].clientHeight + document["documentElement"].scrollTop - panelHeight;
			var leftPosition = document["documentElement"].clientWidth + document["documentElement"].scrollLeft - panelWidth;
			$("#myFavorites-panel").css("top",topPosition+"px");
			$("#myFavorites-panel").css("left",leftPosition+"px");
		}
		
		//dirty flag shows whether client-side storage is out of date
		function refreshPanel(dirtyFlag){
			panelRetrievalAction(dirtyFlag, function(panelData){
				showPanel(panelData);
				
				//fix some css-styles for Internet Explorer
				var liWidth = $("#myFavorites-panel li").outerWidth(true);
				var ulSize = $("#myFavorites-panel ul").children("li").size();
				var paddingSum = (parseInt($("#myFavorites-panel ul").css("padding-right"))) + (parseInt($("#myFavorites-panel form").css("padding-left")));	
				var panelWidth = paddingSum + liWidth*ulSize;
				var panelElement = $("#myFavorites-panel-inner").not(".closed");

				if($.browser.msie && jQuery.browser.version.substr(0,3)=="6.0"){
					if(!panelElement.hasClass('closed'))
						panelElement = $("#myFavorites-panel");
					
					$("#myFavorites-panel-tab").width($("#myFavorites-panel-tab h2").width());
				}
				
				var panelTabWidth = $("#myFavorites-panel-tab").outerWidth();
				
				if(!$("#myFavorites-panel-inner").hasClass('closed'))
					panelTabWidth += 11;
					
				if(panelWidth && (panelWidth > panelTabWidth))
					panelElement.width(panelWidth);
				else
					panelElement.width(panelTabWidth);
			
				/* Append Shim Layer and fix position for IE6 */
				if (jQuery.browser.msie && parseInt(jQuery.browser.version)<=6) {
					var shimLayer = $('<iframe class="shim-layer">');
					shimLayer.height(panelElement.height());
					 
					if(! $('#myFavorites-panel-inner').hasClass('closed'))
						shimLayer.css({ width:  panelElement.width()+9, left: '-11px'});
					
					 shimLayer.appendTo('#myFavorites-panel');
					 positionPanel();
				}
			});	
		}
		
		function panelRetrievalAction(dirtyFlag, callbackForPanelData){
			panelData = getFlashValue("panelData");
			if(panelData == null || dirtyFlag.panelDataDirty){
				// add timestamp as parameter in order to deal with IE ajax request caching problems!
				$.get('/c-FavoritesPanel',{opened: getPanelPreferenceOpen(), nocache: new Date().getTime()} , function(data){
					if (data.indexOf("myFavorites-panel-inner") != -1) {
						writeFlashValue("panelData",data);
						writeFlashValue("panelTimestamp",new Date().getTime());
						callbackForPanelData(data);
					}
				});
			} else {
				callbackForPanelData(panelData);
			}
		}
		
		function panelDataExpired(){
			var panelDataTimestamp = getFlashValue("panelTimestamp");    		  
			//panelData should always be refreshed after 1 day 
			if( new Date().getTime() - panelDataTimestamp > 86400000)			
				return true;
			return false;		  
	    }
		
		function hidePanel(){
			writeFlashValue("panelOpen" , "false");	
			refreshPanel({panelDataDirty:true});
		}
		
		function openPanel(){
			writeFlashValue("panelOpen" , "true");	
			refreshPanel({panelDataDirty:true});
		}	
		
		function getPanelPreferenceOpen(){
			if(getFlashValue("panelOpen") == "true")
				return true;
			//default preference is closed
			if(getFlashValue("panelOpen")  == null)
				return false;
			if(getFlashValue("panelOpen") == "false")
				return false;
		}
		
		function firstPanelVisit(){			
			return getFlashValue("panelOpen") == null;
		}		
       	
       	function showPanel(data){
	       	$('#myFavorites-panel').html(data);
       	}
       	
       	function flashAvailable(){	
       		//feature is supported since flashplayer version 9
       		if(swfobject.getFlashPlayerVersion().major == (0 || 6 || 7 || 8) )
       			return false;
			return true;
       	}      	        
         
         function getFlashValue(key){
			var obj = swfobject.getObjectById("flashCookie");                          					
			if (obj && typeof obj.getFlashCookieValue != "undefined") {
				if (key == "panelData" || key == "panelTimestamp") {
					key += "-" + this.domain;
				}
 				return obj.getFlashCookieValue(key);    
			}
			else 	throw "FlashCookie no Access";
          } 
          
          function writeFlashValue(key,value){                      
            var obj = swfobject.getObjectById("flashCookie");              					
			if (obj && typeof obj.setFlashCookieValue != "undefined") {
				if (key == "panelData" || key == "panelTimestamp") {
					key += "-" + this.domain;
				}
				obj.setFlashCookieValue(key,value);
			}
			else	throw "FlashCookie no Access";
          }   
          
      function panelActivated(){
       	return getPanelDisplayed() && flashAvailable();
      } 
          
			function getFavoriteAdIds(){
				// remove starting snippet which is the key (saved-ad-ids sit right to '.*?saved=')
				var savedAds=readCookie("ad_ids").replace(/.*?saved=/,"");
				// get rid of timestamps (pattern :3333333)
				savedAds=savedAds.replace(/:\d+/g,"");
				// get rid of ad-id separator &
				return savedAds.split("&");
			}
			
			//TODO: check if there is not already a common lib-function for reading cookie values
			function readCookie(n) {
				var cookiecontent = new String();
				if(document.cookie.length > 0) {
					var cookiename = n+ '=';
					var cookiebegin = document.cookie.indexOf(cookiename);
					var cookieend = 0;
				if(cookiebegin > -1) {
					cookiebegin += cookiename.length;
					cookieend = document.cookie.indexOf(";",cookiebegin);
					if(cookieend < cookiebegin) { cookieend = document.cookie.length; }
						cookiecontent = document.cookie.substring(cookiebegin,cookieend);
					}
				}
				return unescape(cookiecontent);
			}
                

	//PUBLIC API, visible to clients
	return{

		init:function(domain, panelDisplayed){
			setDomain(domain);
			setPanelDisplayed(panelDisplayed);
			
			if (panelDisplayed) {
				//no panel for non flash, all further methods for panel retrieval aren't checking flash availability again, because 
				//they cannot be reached (no callbacks active) and thus are protected by non-flash behaviour.		
				if(flashAvailable()){
				
					if(panelDataExpired()){
						//sync-data (active ads could have gotten inactive by now)
						$.get('/c-SaveAd', {Action:'sync'},function(data){
							refreshPanel( {panelDataDirty:true} );
						});
					}
					else
						refreshPanel( {panelDataDirty:false} );
				}
			}
		},

		addFavorite: function(adId, addSuccessCallback){	
			if(panelActivated())
				//panel not initialized yet, then user should be shown the panel 
				if(firstPanelVisit())
					writeFlashValue("panelOpen" , "true");	
				
			// use post to write data...
			$.post('/c-SaveAd', {AdId:adId ,Action:'add',AdActivityType:'ViewAd'},function(data){
				if (data == 'ok') {
					addSuccessCallback(adId);
					if (panelActivated()) {
						refreshPanel({panelDataDirty:true});
					}
				} else if (data.indexOf('pagestatusajax') != -1) {
					// show error message - TODO: better way to see of an error message needs to be shown.
					$('#pagestatus_new').css("display","");
					$('#pagestatus_new').html(data);
					// go to top of the page in case an error is displayed!
					window.location.href = "#top";
				}
        	});
		},	  
		
		removeFavorite: function(adId, removeSuccessCallback){
			if(panelActivated())
				//panel not initialized yet, then user should be shown the panel 
				if(firstPanelVisit() && panelActivated())
					writeFlashValue("panelOpen" , "true");
					
			// use post to remove ad
			$.post('/c-SaveAd', {AdId:adId ,Action:'remove',AdActivityType:'ViewAd'},function(data){
				if (data == 'ok') {
					removeSuccessCallback(adId);
					if (panelActivated()) {
						refreshPanel({panelDataDirty:true});
					}
				}
        	});    
		},
    
	    isFavorite: function(adId){
				var isSaved=false;
				$.each(getFavoriteAdIds(),function(i,savedAdId){
					if(adId == savedAdId)
						isSaved=true;
				});			
				return isSaved;
	    },	
		
		openPanel: function(){
			openPanel();
		},
		
		flashAvailable: function(){
			return flashAvailable();
		},
		
		closePanel: function(){
			hidePanel();
		},
		
		positionPanel: function(){
			positionPanel();
		},
		
		refreshPanelStorage: function(){
			panelRetrievalAction({panelDataDirty:true}, function(panelData){});				
		}
	};
		
}(); 

$(document).ready(function() {
	$('input:text').inputFields();
});


