
/*
 * SearchAssistant
 * - TO DEBUG: set this.showConsole = true in the initialize function
 * - NO NEED TO COMPRESS AS livesearch_compressed.js
*/

SearchAssistant = Class.create({

	options: $H({
		className: "suggest",
		minimumCharacters: 3,
		timeout: 10000,
		delay: 40,
		displayNoResults: true,
		noResultsMessage: "No Suggestion",
		cache: true,
		templateField: null,
		maxItems: 10,
		onAjaxError: null,
		url: "/search/suggest.ashx",
		watermark: "Destinations, hotels, attractions, etc.",
		filter: ""
	}),

	initialize: function(id, options){	  
		//show console Messages
		this.showConsole = false;

		// get field
		this.field = $(id);
		if (!this.field) {
			throw ("SearchAssistant requires an input field ID to initialize");
		}
	        
		// Turn off autocomplete on IE only; FF will respond weirdly to arrow keys
		// if the attribute is added for some reason
		//if (!Prototype.Browser.Gecko) {
		$(this.field).writeAttribute({
			autocomplete: 'off'
		});
		//}

		// Initialize variables
		this.InputValue = "";
		this.InputLength = 0;
		// parameters object
		this.options = this.options.merge(options);
		this.ResponseCache = new Hash();
		// Moved template parsing out out init to prevent initial start-up delays
		this.TemplateInitialized = false;
		this.EventsBound = false;

		this.field.observe('focus', function(event){
			if (!this.EventsBound) {
				this.setEvents();
			}
		}.bind(this));
        
		// Handle the case where javascript initialization is late
		if ($(this.field).present() && $F(this.field) != this.options.get("watermark") && !$(this.field).readAttribute("prefill")) {
			if (this.showConsole)
				console.warn("Detected late JavaScript initialization");	
			this.getSuggestions($F(this.field));
		}
	},
	onKeyPress: function(e){
		var key = e.keyCode || e.which;

		switch (key) {
			case Event.KEY_RETURN:
				Event.stop(e);
				this.setHighlightedValue(e);
				break;
			case Event.KEY_ESC:
				this.blur();
				break;
		}
	},
	onKeyUp: function(e){
		var key = e.keyCode || e.which;

		if (key == Event.KEY_UP || key == Event.KEY_DOWN) {
			this.changeHighlight(key);
			Event.stop(e);
		}
		else {
			this.getSuggestions(this.field.value);
		}
	},
	setEvents: function(){
		this.field.observe('keydown', function(e){
			return this.onKeyPress(e);
		}
.bind(this));
		this.field.observe('keyup', function(e){
			return this.onKeyUp(e);
		}
.bind(this));
		this.field.observe('blur', function(){
			this.blur();
		}
.bind(this));
		this.EventsBound = true;
	},
	getSuggestions: function(val, searchType){       
        
		// input the same? do nothing
		if (val == this.InputValue) {
			if (this.showConsole)
				console.info("Input matches previous call, prevent AJAX call");
			return false;
		}
		else {
			if (!this.TemplateInitialized) {
				this.Template = TrimPath.parseDOMTemplate(this.options.get("templateField"));
				this.TemplateInitialized = true;
			}
			if (this.showConsole)
				console.info("New input string found, preparing AJAX call...");
		}

		this.InputValue = val;

		// Input length is less than the min required to trigger a request
		if (val.length < this.options.get("minimumCharacters")) {
			this.InputLength = val.length;
			if (this.showConsole)
				console.info("Input is less than minimumCharacters, preventing AJAX call");
			return false;
		}

		// Check our response cache to prevent unnecessary AJAX calls for the same input
		if (this.options.get("cache") && this.ResponseCache.get(val)) {
			if (this.showConsole)
				console.log("Found local cached suggestions for this input");
			this.renderList(this.ResponseCache.get(val));
			return false;
		}

		clearTimeout(this.ajID); // ajax id timer
		this.ajID = setTimeout(function(){
			this.doAjaxRequest(this.InputValue, searchType);
		}
.bind(this), this.options.get("delay"));
		return false;
	},
	doAjaxRequest: function(input, searchType){
		// Check that the user has not changed the input
		if (input != this.field.value) {
			if (this.showConsole)
				console.warn("Input has changed with new value");
			return false;
		}

		this.field.addClassName('busyField');

		var opt = {
			on404: function(exception){
				if (this.showConsole) {
					if (console.error) {
						console.error('Error (404): ' + exception.statusText);
					}
				}
			},
			// Handle other errors
			onFailure: function(exception){
				if (this.showConsole) {
					if (console.error) {
						console.error('AJAX Error : ' + exception.statusText);
					}
				}
				if (typeof(this.options.get('onAjaxError')) == 'function') {
					this.options.get('onAjaxError')(exception);
				}
			},
			onSuccess: function(transport){
				//A replacement hack for enumerating locations.
				if (this.showConsole)
					console.info("Ajax request success");
				//Temporary hack until Lucene search result names are changed to Results to their corresponding identifier (BusinessCards, Locations, etc...)
				if (searchType == "businesscard")
					transport.responseText=transport.responseText.replace("\"Results\":","'BusinessCards':");
				else if (searchType == 'location')
					transport.responseText=transport.responseText.replace("\"Results\":","'Locations':");

				transport.responseText=transport.responseText.replace("\"Location\":{","\"Location\":[{");
				transport.responseText=transport.responseText.replace("\"}}}}}},'responseStatus':","\"}}}]}}},'responseStatus':");
				transport.responseText=transport.responseText.replace("}}}},\"BusinessCards\":","}}}]},'BusinessCards':");
				transport.responseText=transport.responseText.replace(":{\"BusinessCard\":{",":{\"BusinessCard\":[{");
				transport.responseText=transport.responseText.replace("\"}}}},'responseStatus':","\"}]}}},'responseStatus':");
				
				if (this.showConsole)
					console.info("Replace response text success");
				this.setSuggestions(transport.responseText.evalJSON(), input);
			}
.bind(this)
		};
		var oSearchTypeParam = (searchType) ? '&searchType=' + searchType : '' ;
		var oFilter = this.options.get("filter") ? this.options.get("filter") : "";	
		new Ajax.Request(this.options.get("url") + '?q=' + escape(oFilter + this.InputValue).replace('+','%2B','g').replace('%20','+','g').replace('%2C','+') + '&output=json&from=1&to=' + this.options.get("maxItems") + oSearchTypeParam, opt);
		this.field.removeClassName('busyField');
	},
	setSuggestions: function(jsonData, input){
		// If field input no longer matches what was passed to the request don't show the suggestions
		if (input != this.field.value) {
			return false;
		}

		if (this.showConsole)
			console.info("Inside setSuggestions");
				
		this.Holder = 'suggest_' + this.field.id;

		if (this.options.get("cache")) {
			this.ResponseCache.set(this.InputValue, jsonData);
			if (this.showConsole) {
				console.info("Adding response to the cache");
				console.debug(this.ResponseCache.inspect());
			}
		}

		this.renderList(jsonData);
	},
	renderList: function(data){
		//var p = this;

		// clear list removal timeout
		//this.killTimeout();

		// if no results, and displayNoResults is false, do nothing
		if (data.responseData.Result.TotalResultsAvailable === 0 && !this.options.get("displayNoResults")) {
			return false;
		}

		var pos = $(this.field).cumulativeOffset();

		// Add extra values to the data for template parsing
		data.ContainerLeftOffset = pos[0] + "px";
		data.ContainerTopOffset = pos[1] + this.field.offsetHeight + "px";
		data.ContainerID = this.Holder;
		data.ContainerClassname = this.options.get("className");
		data.NoResultsMessage = this.options.get("noResultsMessage");

		var result = this.Template.process(data);
		if (this.showConsole)
			console.warn("The result is " + result);

		if ($(this.Holder)) 
			Element.replace($(this.Holder), result);
		else {
			$$('body')[0].insert(result, {
				position: 'after'
			});
		   
			$(this.Holder).observe('click', function(event){
				this.setHighlightedValue(event);
			}
.bind(this));
		$(this.Holder).observe('mouseover', function(event){
			 this.setHighlight(null, null, event);
		}
.bind(this));
		/*$(this.Holder).observe('mouseout', function(){
			 this.resetTimeout();
		}
.bind(this));*/
            
		}
		
		$(this.Holder).setOpacity(1.0);
        
		// remove list after interval
		/*this.toID = setTimeout(function(){
		p.blur();
		}, this.options.get("timeout"));*/
	},
	changeHighlight: function(key){
		var list = $("suggestionItems_" + this.Holder);
		if (!list) 
			return false;

		var n = $$('#suggestionItems_' + this.Holder + ' li a').indexOf($$('#suggestionItems_' + this.Holder + ' li a.suggestHighlight')[0]);
		n = (key == Event.KEY_DOWN || key == Event.KEY_TAB) ? n + 1 : n - 1; // false assumed to be Event.KEY_UP		
		n = (n >= $$('#suggestionItems_' + this.Holder + ' li a').length) ? $$('#suggestionItems_' + this.Holder + ' li a').length - 1 : ((n < 0) ? 0 : n);

		if (key == Event.KEY_DOWN || key == Event.KEY_UP) {
			this.setHighlight(n, true);
		}
		else {
			this.setHighlight(n);
		}
	},
	setHighlight: function(n, keyBoard, event){
		if (!event) {
			if (!$('suggestionItems_' + this.Holder)) 
				return false;
			this.clearHighlight();
			$$('#suggestionItems_' + this.Holder + ' li a')[n].addClassName('suggestHighlight');
			if (keyBoard && !$$('.suggestHighlight')[0].up().hasClassName('suggestCategory')) {
				this.field.value = $$('.suggestHighlight')[0].up().readAttribute('name');
			}
		}
		else {
			var oElement = Event.findElement(event, 'A');
			if (oElement) {
				this.clearHighlight();
				$(oElement).addClassName('suggestHighlight');
				if (keyBoard) {
					this.field.value = $(oElement).up().readAttribute('name');
				}
			}
		}
		//this.killTimeout();
	},
	clearHighlight: function(){
		if ($$('#suggestionItems_' + this.Holder + ' li a.suggestHighlight').length == 1) {
			$$('#suggestionItems_' + this.Holder + ' li a.suggestHighlight')[0].removeClassName('suggestHighlight');
		}
	},
	setHighlightedValue: function(event){
		var oClickedElement = Event.findElement(event, 'LI');
		if (oClickedElement) {
			if ($(oClickedElement).hasClassName('ac_warning')) {
				$('Top_SearchSubmit').click();
			}
			else {
				this.InputValue = this.field.value = $(oClickedElement).readAttribute('name');
				this.blur();
				location.href = $(oClickedElement).down().href;
			}
		   
			// move cursor to end of input (safari)
			if (this.field.selectionStart) 
				this.field.setSelectionRange(this.InputValue.length, this.InputValue.length);
		}
		else {
			if ($$('#suggestionItems_' + this.Holder + ' li a.suggestHighlight').length == 1) {
				location.href = $$('#suggestionItems_' + this.Holder + ' li a.suggestHighlight')[0].href;
			}
			else {
				location.href = "/search/results.aspx?phrase=" + escape(this.InputValue).replace('+','%2B','g').replace('%20','+','g');
			}
			return;
		}
	},
	killTimeout: function(){
		clearTimeout(this.toID);
	},
	resetTimeout: function(){
		this.killTimeout();
		var p = this;
		this.toID = setTimeout(function(){
			this.blur();
		}
.bind(this), this.options.get("timeout"));
	},
	blur: function(){
		this.killTimeout();
		if ($(this.Holder)) {
			this.fadeOut(0.3, null);
		}
	},
	fadeOut: function(seconds, callback){
		new Effect.BlindUp($(this.Holder), {
			duration: seconds,
			afterFinish: callback
		});
	}
});



var SearchAssistantUtil = new Object();
SearchAssistantUtil.highlightSearchResult = function(searchResultValue, input){ 
	var userInput = (input == null) ? $F($$('#searchGlobal input')[0]).strip() : $F(input).strip() ;
	var oMatchRegex = new RegExp(userInput.replace(/[[\]*\\.{}]/g,function(pX){return "\\"+pX;}).replace(/\s+/g, "|"), 'ig');
	return searchResultValue.replace(oMatchRegex, function(match){ 
		return "<b>" + match + "</b>";
	});  
}

// TRIMPATH TEMPLATE
eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('4 b;(8(){5(b==c)b=Q 2H();5(b.1R==c)b.1R=8(2q){a 1N(2q)};4 2e;5(1g.1c.1X==c)1g.1c.1X=8(){5(q.7===0){a 2e}a q[--q.7]};5(1g.1c.9==c)1g.1c.9=8(){G(4 i=0;i<2f.7;++i){q[q.7]=2f[i]}a q.7};b.1Q=8(1u,1J,H){5(H==c)H=b.E;4 1t=2w(1u,1J,H);4 1p=b.1R(1t,1J,1);5(1p!=c)a Q H.1Z(1J,1u,1t,1p,H);a c};2n{1K.1c.1B=8(z,1L){4 1M=b.1Q(q,c);5(1M!=c)a 1M.1B(z,1L);a q}}2p(e){}b.E={};b.E.27="2r|G|5|2g|I|4|1T";b.E.2c={"5":{C:1,N:"5 (",16:") {",1E:1},"I":{C:0,N:"} I {"},"2g":{C:0,N:"} I 5 (",16:") {",1H:"1r"},"/5":{C:-1,N:"}"},"G":{C:1,1E:3,1I:8(V,x,B,A){5(V[2]!="1h")1f Q A.X(B,x.u,"2K G 2L 1G: "+V.L(\' \'));4 P=V[1];4 Y="2M"+P;a["4 ",Y," = ",V[3],";","4 D;","5 (2i(D) == \'2m\' || !D.7) D = Q 1g();","D[D.7] = 0;","5 ((",Y,") != c) { ","4 ",P,"2h = 0;","G (4 ",P,"22 1h ",Y,") { ",P,"2h++;","5 (2i(",Y,"[",P,"22]) == \'8\') {2O;}","D[D.7 - 1]++;","4 ",P," = ",Y,"[",P,"22];"].L("")}},"2r":{C:0,N:"} } 5 (D[D.7 - 1] == 0) { 5 (",16:") {",1H:"1r"},"/G":{C:-1,N:"} }; 2R D[D.7 - 1];"},"4":{C:0,N:"4 ",16:";"},"1T":{C:1,1I:8(V,x,B,A){4 1S=V[1].1n(\'(\')[0];a["4 ",1S," = 8",V.2b(1).L(\' \').w(1S.7),"{ 4 1U = []; 4 T = { U: 8(m) { 5 (m) 1U.9(m); } }; "].L(\'\')}},"/1T":{C:-1,N:" a 1U.L(\'\'); };"}};b.E.1o={"2U":8(v){a""},"2j":8(s){a 1K(s).j(/&/g,"&2V;").j(/</g,"&2s;").j(/>/g,"&23;")},"2W":8(s){a 1K(s).2X()},"2Y":8(s,d){a s!=c?s:d}};b.E.1o.h=b.E.1o.2j;b.E.1Z=8(B,1u,1t,1p,A){q.1B=8(z,1k){5(z==c)z={};5(z.1l==c)z.1l={};5(z.2k==c)z.2k=8(2l){a(z[2l]!=2m)};G(4 k 1h A.1o){5(z.1l[k]==c)z.1l[k]=A.1o[k]}5(1k==c)1k={};4 1y=[];4 2o={U:8(m){1y.9(m)}};2n{1p(2o,z,1k)}2p(e){5(1k.2Z==1r)1f e;4 f=Q 1K(1y.L("")+"[30: "+e.20()+(e.1d?\'; \'+e.1d:\'\')+"]");f["31"]=e;a f}a 1y.L("")};q.1v=B;q.33=1u;q.34=1t;q.20=8(){a"b.1Z ["+B+"]"}};b.E.X=8(1v,u,1d){q.1v=1v;q.u=u;q.1d=1d};b.E.X.1c.20=8(){a("b 1M X 1h "+q.1v+": u "+q.u+", "+q.1d)};4 2w=8(o,B,A){o=2u(o);4 6=["4 29 = 8(T, 2x, 1Y) { 35 (2x) {"];4 x={15:[],u:1};4 W=-1;1w(W+1<o.7){4 p=W;p=o.R("{",p+1);1w(p>=0){4 Z=o.R(\'}\',p+1);4 y=o.w(p,Z);4 21=y.2d(/^\\{(24|25|1N)/);5(21){4 17=21[1];4 1D=p+17.7+1;4 1b=o.R(\'}\',1D);5(1b>=0){4 1j;5(1b-1D<=0){1j="{/"+17+"}"}I{1j=o.w(1D+1,1b)}4 1x=o.R(1j,1b+1);5(1x>=0){1q(o.w(W+1,p),6);4 11=o.w(1b+1,1x);5(17==\'24\'){1m(11,6)}I 5(17==\'25\'){1m(26(11),6)}I 5(17==\'1N\'){5(11!=c&&11.7>0)6.9(\'T.U( (8() { \'+11+\' })() );\')}p=W=1x+1j.7-1}}}I 5(o.O(p-1)!=\'$\'&&o.O(p-1)!=\'\\\\\'){4 1O=(o.O(p+1)==\'/\'?2:1);5(o.w(p+1O,p+10+1O).2y(b.E.27)==0)1e}p=o.R("{",p+1)}5(p<0)1e;4 Z=o.R("}",p+1);5(Z<0)1e;1q(o.w(W+1,p),6);2a(o.w(p,Z+1),x,6,B,A);W=Z}1q(o.w(W+1),6);5(x.15.7!=0)1f Q A.X(B,x.u,"2z, 2A 1G(s): "+x.15.L(","));6.9("}}; 29");a 6.L("")};4 2a=8(18,x,6,B,A){4 F=18.2b(1,-1).1n(\' \');4 y=A.2c[F[0]];5(y==c){1q(18,6);a}5(y.C<0){5(x.15.7<=0)1f Q A.X(B,x.u,"2B 2C 2D 2F 2d 2G 2I 1G: "+18);x.15.1X()}5(y.C>0)x.15.9(18);5(y.1E!=c&&y.1E>=F.7)1f Q A.X(B,x.u,"1G 2Q 2S 2T: "+18);5(y.1I!=c)6.9(y.1I(F,x,B,A));I 6.9(y.N);5(y.16!=c){5(F.7<=1){5(y.1H!=c)6.9(y.1H)}I{G(4 i=1;i<F.7;i++){5(i>1)6.9(\' \');6.9(F[i])}}6.9(y.16)}};4 1q=8(l,6){5(l.7<=0)a;4 M=0;4 K=l.7-1;1w(M<l.7&&(l.O(M)==\'\\n\'))M++;1w(K>=0&&(l.O(K)==\' \'||l.O(K)==\'\\t\'))K--;5(K<M)K=M;5(M>0){6.9(\'5 (1Y.2t == 1r) T.U("\');4 s=l.w(0,M).j(\'\\n\',\'\\\\n\');5(s.O(s.7-1)==\'\\n\')s=s.w(0,s.7-1);6.9(s);6.9(\'");\')}4 1C=l.w(M,K+1).1n(\'\\n\');G(4 i=0;i<1C.7;i++){2v(1C[i],6);5(i<1C.7-1)6.9(\'T.U("\\\\n");\\n\')}5(K+1<l.7){6.9(\'5 (1Y.2t == 1r) T.U("\');4 s=l.w(K+1).j(\'\\n\',\'\\\\n\');5(s.O(s.7-1)==\'\\n\')s=s.w(0,s.7-1);6.9(s);6.9(\'");\')}};4 2v=8(u,6){4 13=\'}\';4 1a=-1;1w(1a+13.7<u.7){4 1i="${",1A="}";4 12=u.R(1i,1a+13.7);5(12<0)1e;5(u.O(12+2)==\'%\'){1i="${%";1A="%}"}4 1z=u.R(1A,12+1i.7);5(1z<0)1e;1m(u.w(1a+13.7,12),6);4 J=u.w(12+1i.7,1z).j(/\\|\\|/g,"#@@#").1n(\'|\');G(4 k 1h J){5(J[k].j)J[k]=J[k].j(/#@@#/g,\'||\')}6.9(\'T.U(\');1V(J,J.7-1,6);6.9(\');\');1a=1z;13=1A}1m(u.w(1a+13.7),6)};4 1m=8(l,6){5(l==c||l.7<=0)a;l=l.j(/\\\\/g,\'\\\\\\\\\');l=l.j(/\\n/g,\'\\\\n\');l=l.j(/"/g,\'\\\\"\');6.9(\'T.U("\');6.9(l);6.9(\'");\')};4 1V=8(J,1F,6){4 1P=J[1F];5(1F<=0){6.9(1P);a}4 F=1P.1n(\':\');6.9(\'1l["\');6.9(F[0]);6.9(\'"](\');1V(J,1F-1,6);5(F.7>1){6.9(\',\');6.9(F[1])};6.9(\')\')};4 2u=8(f){f=f.j(/\\t/g,"    ");f=f.j(/\\r\\n/g,"\\n");f=f.j(/\\r/g,"\\n");f=f.j(/^(\\s*\\S*(\\s+\\S+)*)\\s*$/,\'$1\');a f};4 26=8(f){f=f.j(/^\\s+/g,"");f=f.j(/\\s+$/g,"");f=f.j(/\\s+/g," ");f=f.j(/^(\\s*\\S*(\\s+\\S+)*)\\s*$/,\'$1\');a f};b.28=8(1s,19,H){5(19==c)19=2E;4 1W=19.2J(1s);4 14=1W.2N;5(14==c)14=1W.32;14=14.j(/&2s;/g,"<").j(/&23;/g,">");a b.1Q(14,1s,H)};b.2P=8(1s,z,1L,19,H){a b.28(1s,19,H).1B(z,1L)}})();',62,192,'||||var|if|funcText|length|function|push|return|TrimPath|null|||result||||replace||text|||body|begStmt|this||||line||substring|state|stmt|context|etc|tmplName|delta|__LENGTH_STACK__|parseTemplate_etc|parts|for|optEtc|else|exprArr|nlSuffix|join|nlPrefix|prefix|charAt|iterVar|new|indexOf||_OUT|write|stmtParts|endStmtPrev|ParseError|listVar|endStmt||blockText|begExpr|endMarkPrev|content|stack|suffix|blockType|stmtStr|optDocument|endExprPrev|blockMarkerEnd|prototype|message|break|throw|Array|in|begMark|blockMarker|flags|_MODIFIERS|emitText|split|modifierDef|func|emitSectionText|true|elementId|funcSrc|tmplContent|name|while|blockEnd|resultArr|endExpr|endMark|process|lines|blockMarkerBeg|paramMin|index|statement|paramDefault|prefixFunc|optTmplName|String|optFlags|template|eval|offset|expr|parseTemplate|evalEx|macroName|macro|_OUT_arr|emitExpression|element|pop|_FLAGS|Template|toString|blockrx|_index|gt|cdata|minify|scrubWhiteSpace|statementTag|parseDOMTemplate|TrimPath_Template_TEMP|emitStatement|slice|statementDef|match|UNDEFINED|arguments|elseif|_ct|typeof|escape|defined|str|undefined|try|resultOut|catch|src|forelse|lt|keepWhitespace|cleanWhiteSpace|emitSectionTextLine|parse|_CONTEXT|search|unclosed|unmatched|close|tag|does|document|not|any|Object|previous|getElementById|bad|loop|__LIST__|value|continue|processDOMTemplate|needs|delete|more|parameters|eat|amp|capitalize|toUpperCase|default|throwExceptions|ERROR|exception|innerHTML|source|sourceFunc|with'.split('|'),0,{}))

/*
   Behaviour v1.1 by Ben Nolan, June 2005. Based largely on the work
   of Simon Willison (see comments by Simon below).

   Description:
   	
   	Uses css selectors to apply javascript behaviours to enable
   	unobtrusive javascript in html documents.
   	
   Usage:   
   
	var myrules = {
		'b.someclass' : function(element){
			element.onclick = function(){
				alert(this.innerHTML);
			}
		},
		'#someid u' : function(element){
			element.onmouseover = function(){
				this.innerHTML = "BLAH!";
			}
		}
	};
	
	Behaviour.register(myrules);
	
	// Call Behaviour.apply() to re-apply the rules (if you
	// update the dom, etc).

   License:
   
   	This file is entirely BSD licensed.
   	
   More information:
   	
   	http://ripcord.co.nz/behaviour/
   
*/   

var Behaviour = {
	list : new Array,
	
	register : function(sheet){
		Behaviour.list.push(sheet);
	},
	
	start : function(){
		Behaviour.addLoadEvent(function(){
			Behaviour.apply();
		});
	},
	
	apply : function(){
		for (h=0;sheet=Behaviour.list[h];h++){
			for (selector in sheet){
				list = document.getElementsBySelector(selector);
				
				if (!list){
					continue;
				}

				for (i=0;element=list[i];i++){
					sheet[selector](element);
				}
			}
		}
	},
	
	addLoadEvent : function(func){
		if (typeof Prototype == 'undefined') {		
			var oldonload = window.onload;
			
			if (typeof window.onload != 'function') {
				window.onload = func;
			} else {
				window.onload = function() {
					oldonload();
					func();
				}
			}
		} else {
			document.observe("dom:loaded", function() {
				func();			
			});		
		}
	}
}

Behaviour.start();

/*
   The following code is Copyright (C) Simon Willison 2004.

   document.getElementsBySelector(selector)
   - returns an array of element objects from the current document
     matching the CSS selector. Selectors can contain element names, 
     class names and ids and can be nested. For example:
     
       elements = document.getElementsBySelect('div#main p a.external')
     
     Will return an array of all 'a' elements with 'external' in their 
     class attribute that are contained inside 'p' elements that are 
     contained inside the 'div' element which has id="main"

   New in version 0.4: Support for CSS2 and CSS3 attribute selectors:
   See http://www.w3.org/TR/css3-selectors/#attribute-selectors

   Version 0.4 - Simon Willison, March 25th 2003
   -- Works in Phoenix 0.5, Mozilla 1.3, Opera 7, Internet Explorer 6, Internet Explorer 5 on Windows
   -- Opera 7 fails 
*/

function getAllChildren(e) {
  // Returns all children of element. Workaround required for IE5/Windows. Ugh.
  return e.all ? e.all : e.getElementsByTagName('*');
}

document.getElementsBySelector = function(selector) {
  // Attempt to fail gracefully in lesser browsers
  if (!document.getElementsByTagName) {
    return new Array();
  }
  // Split selector in to tokens
  var tokens = selector.split(' ');
  var currentContext = new Array(document);
  for (var i = 0; i < tokens.length; i++) {
    token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;
    if (token.indexOf('#') > -1) {
      // Token is an ID selector
      var bits = token.split('#');
      var tagName = bits[0];
      var id = bits[1];
      var element = document.getElementById(id);
      if (tagName && element.nodeName.toLowerCase() != tagName) {
        // tag with that ID not found, return false
        return new Array();
      }
      // Set currentContext to contain just this element
      currentContext = new Array(element);
      continue; // Skip to next token
    }
    if (token.indexOf('.') > -1) {
      // Token contains a class selector
      var bits = token.split('.');
      var tagName = bits[0];
      var className = bits[1];
      if (!tagName) {
        tagName = '*';
      }
      // Get elements matching tag, filter them for class selector
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            elements = currentContext[h].getElementsByTagName(tagName);
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      continue; // Skip to next token
    }
    // Code to deal with attribute selectors
    if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
      var tagName = RegExp.$1;
      var attrName = RegExp.$2;
      var attrOperator = RegExp.$3;
      var attrValue = RegExp.$4;
      if (!tagName) {
        tagName = '*';
      }
      // Grab all of the tagName elements within current context
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            elements = currentContext[h].getElementsByTagName(tagName);
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      var checkFunction; // This function will be used to filter the elements
      switch (attrOperator) {
        case '=': // Equality
          checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
          break;
        case '~': // Match one of space seperated words 
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
          break;
        case '|': // Match start with value followed by optional hyphen
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
          break;
        case '^': // Match starts with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
          break;
        case '$': // Match ends with value - fails with "Warning" in Opera 7
          checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
          break;
        case '*': // Match ends with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
          break;
        default :
          // Just test for existence of attribute
          checkFunction = function(e) { return e.getAttribute(attrName); };
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (checkFunction(found[k])) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      // alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue);
      continue; // Skip to next token
    }
    
    if (!currentContext[0]){
    	return;
    }
    
    // If we get here, token is JUST an element (not a class or ID selector)
    tagName = token;
    var found = new Array;
    var foundCount = 0;
    for (var h = 0; h < currentContext.length; h++) {
      var elements = currentContext[h].getElementsByTagName(tagName);
      for (var j = 0; j < elements.length; j++) {
        found[foundCount++] = elements[j];
      }
    }
    currentContext = found;
  }
  return currentContext;
}

/* That revolting regular expression explained 
/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/
  \---/  \---/\-------------/    \-------/
    |      |         |               |
    |      |         |           The value
    |      |    ~,|,^,$,* or =
    |   Attribute 
   Tag
*/
var oIgoUgoJSCreated = (typeof(IgoUgoJS) != 'undefined');
var IgoUgoJS = {
	loadedUris:[],
	loaded_modules_:[],
	loading_modules_:[],
	addedToLoadingCount:[]
};

/*
 #####################################
 Config
 #####################################
*/
// To override the properties, simply create an object called IgoUgoJSConfigExt with properties the name of the function in IgoUgoJS.Config.
// E.g.:
// IgoUgoJSConfigExt = {
//  baseRep:'mypath/igougo', // for BaseRep()
//  beRep:'mypath/be' // for BERep()
//  ...
// }
IgoUgoJS.Config = {
	initialize: function() {
		this.configs = [];
		// defaults
		this.Set('baseRep', '/global/scripts/igougo');
		this.Set('utilRep', this.BaseRep() + '/util');
		this.Set('depRep', this.BaseRep() + '/dependencies');
		this.Set('packageName', '_package');
		this.Set('compression', 'none');
		this.Set('staticDomain', 'http://static.igougo.com');
	},
	Get: function(pKey) {
		if (!pKey) return;
		return this.configs[pKey];
	},
	Set: function(pKey, pValue) {
		if (!pKey) return;
		return this.configs[pKey] = pValue;
	},
	// ---------------------
	// Folders
	// ---------------------
	BaseRep: function() {
		return this.Get('baseRep');
	},
	UtilRep: function() {
		return this.Get('utilRep');
	},
	DepRep: function() {
		return this.Get('depRep');
	},
	PackageName: function() {
		return this.Get('packageName');
	},
	Compression: function() {
		return this.Get('compression');
	},
	StaticDomain: function() {
		return this.Get('staticDomain');
	}
}
IgoUgoJS.Config.initialize();

/*
#################################################################
IgoUgo Dyn Load (adaptation of dojo)
#################################################################
*/

if (typeof(IgoUgoJSConfigExt) != 'undefined') {
   for (var option in IgoUgoJSConfigExt) {
		IgoUgoJS.Config.Set(option, IgoUgoJSConfigExt[option]);
	}
}

IgoUgoJS.Inspect = function(obj) {
  var info = [];
  if(typeof obj=="string" || 
     typeof obj=="number") {
    return obj;
  } else {
    for(property in obj)
      if(typeof obj[property]!="function")
        info.push(property + ' => ' + 
          (typeof obj[property] == "string" ?
            '"' + obj[property] + '"' :
            obj[property]));
  }
  return ("'" + obj + "' #" + typeof obj + 
    ": {" + info.join(", ") + "}");
}

IgoUgoJS.Require = function() {
   return IgoUgoJS.LoadModule.apply(this, arguments);
}

IgoUgoJS.Provide = function(packname) {
   var syms = packname.split(/\./);
	if(syms[syms.length-1]=="*") syms.pop();
	return IgoUgoJS.EvalObjPath(syms.join("."), true);
}

IgoUgoJS.Eval = function(pContent) {
	return eval(pContent);
}

IgoUgoJS.LoadUri = function(pUri) {
   if(this.loadedUris[pUri]) return;
	var oContents = this.GetText(pUri, null, true);
	if(oContents == null) return 0;
	this.loadedUris[pUri] = true;
	var value = IgoUgoJS.Eval(oContents);
	return 1;
}

IgoUgoJS.LoadUriAndCheck = function(uri, module, cb){
   var ok = true;
	try{
		ok = this.LoadUri(uri, cb);
	}catch(e){
		if (console.error) {
			console.error("Failed loading " + uri + " with error: " + e.toString());
		}
	}
	return (ok && this.FindModule(module, false));
}


IgoUgoJS.GetText = function(pUri, pCallback, pFailOK) {
	var oHttp = Ajax.getTransport();
	if(pCallback){
		oHttp.onreadystatechange = function(){ 
			if((oHttp.readyState == 4)&&(oHttp["status"])){
				if(oHttp.status==200){
					pCallback(oHttp.responseText);
				}
			}
		}
	}
	oHttp.open('GET', pUri, pCallback ? true : false);
	oHttp.send(null);
	if(pCallback){
		return null;
	}
	return oHttp.responseText;
}

IgoUgoJS.ROOT = this;
IgoUgoJS.Undef = function(name, obj) {
	if(!obj){ obj = IgoUgoJS.ROOT; }
	return (typeof obj[name] == "undefined");
}

IgoUgoJS.FindModule = function(modulename, must_exist) {
   var lmn = (new String(modulename)).toLowerCase();
	if(this.loaded_modules_[lmn]){
		return this.loaded_modules_[lmn];
	}
	// see if symbol is defined anyway
	var module = IgoUgoJS.EvalObjPath(modulename);
	if((modulename)&&(typeof module != 'undefined')&&(module)){
	   this.loaded_modules_[lmn] = module;
		return module;
	}
	if(must_exist && console.error){
		console.error("No loaded module named '" + modulename + "'");
	}
	return null;
}

IgoUgoJS.LoadPath = function(relpath, module /*optional*/, cb /*optional*/){
	if((relpath.charAt(0) == '/')||(relpath.match(/^\w+:/))){
		if (console.error) {
			console.error("relpath '" + relpath + "'; must be relative");
		}
	}
	var uri = IgoUgoJS.Config.BaseRep() + '/' + relpath;
	try{
		return ((!module) ? this.LoadUri(uri, cb) : this.LoadUriAndCheck(uri, module, cb));
	}catch(e){
		if (console.error) {
			console.error("Error in LoadPath: " + e.toString());
		}
		return false;
	}
}

IgoUgoJS.LoadModule = function(modulename, exact_only, omit_module_check){
   if(!modulename) return;
	//omit_module_check = this._global_omit_module_check || omit_module_check;
	var module = this.FindModule(modulename, false);
	if(module) return module;
	// protect against infinite recursion from mutual dependencies
	if(IgoUgoJS.Undef(modulename, this.loading_modules_)){
		this.addedToLoadingCount.push(modulename);
	}
	this.loading_modules_[modulename] = 1;
	// convert periods to slashes
	var relpath = modulename.replace(/\./g, '/') + '.js';
	var syms = modulename.split(".");
	var nsyms = modulename.split(".");
	for (var i = syms.length - 1; i > 0; i--) {
		var parentModule = syms.slice(0, i).join(".");
		//var parentModulePath = this.getModulePrefix(parentModule);
		var parentModulePath = parentModule;
		if (parentModulePath != parentModule) {
			syms.splice(0, i, parentModulePath);
			break;
		}
	}
	var last = syms[syms.length - 1];
	// figure out if we're looking for a full package, if so, we want to do
	// things slightly diffrently
	if(last=="*"){
		modulename = (nsyms.slice(0, -1)).join('.');
		while(syms.length){
			syms.pop();
			syms.push(IgoUgoJS.Config.PackageName());
			relpath = syms.join("/") + '.js';
			if(relpath.charAt(0)=="/"){
				relpath = relpath.slice(1);
			}
			ok = this.LoadPath(relpath, ((!omit_module_check) ? modulename : null));
			if(ok){ break; }
			syms.pop();
		}
	}else{
		relpath = syms.join("/") + '.js';
		modulename = nsyms.join('.');
		var ok = this.LoadPath(relpath, ((!omit_module_check) ? modulename : null));
		//alert('Loading mod ' + modulename);
		if((!ok)&&(!exact_only)){
			syms.pop();
			while(syms.length){
				relpath = syms.join('/') + '.js';
				ok = this.LoadPath(relpath, ((!omit_module_check) ? modulename : null));
				if(ok){ break; }
				syms.pop();
				relpath = syms.join('/') + '/'+ IgoUgoJS.Config.PackageName() +'.js';
				if(relpath.charAt(0)=="/"){
					relpath = relpath.slice(1);
				}
				ok = this.LoadPath(relpath, ((!omit_module_check) ? modulename : null));
				if(ok){ break; }
			}
		}

		if((!ok)&&(!omit_module_check)){
			//dojo.raise("Could not load '" + modulename + "'; last tried '" + relpath + "'");
			alert("Could not load '" + modulename + "'; last tried '" + relpath + "'");
		} else {
		   //alert('mod ' + modulename + ' successfully loaded');
		}
	}

	// check that the symbol was defined
	if(!omit_module_check){
		// pass in false so we can give better error
		module = this.FindModule(modulename, false);
		if(!module && console.error){
			console.error("symbol '" + modulename + "' is not defined after loading '" + relpath + "'");
		}
	}
	return module;
}

IgoUgoJS.EvalObjPath = function(objpath, create){
	// fast path for no periods
	if(typeof objpath != "string"){ return IgoUgoJS.ROOT; }
	if(objpath.indexOf('.') == -1){
		if((IgoUgoJS.Undef(objpath, IgoUgoJS.ROOT))&&(create)){
			IgoUgoJS.ROOT[objpath] = {};
		}
		return IgoUgoJS.ROOT[objpath];
	}

	var syms = objpath.split(/\./);
	var obj = IgoUgoJS.ROOT;
	for(var i=0;i<syms.length;++i){
		if(!create){
			obj = obj[syms[i]];
			if((typeof obj == 'undefined')||(!obj)){
				return obj;
			}
		}else{
			if(IgoUgoJS.Undef(syms[i], obj)) {
				obj[syms[i]] = {};
			}
			obj = obj[syms[i]];
		}
	}
	return obj;
}

if (!oIgoUgoJSCreated) {
	/*
	#####################
	Third party libs
	#####################
	*/
	if (typeof(Prototype) == 'undefined' || typeof(Effect) == 'undefined') {
		if (IgoUgoJS.Config.Compression() == 'gzip') {
			document.write('<script type="text/javascript" language="javascript" src="' + IgoUgoJS.Config.StaticDomain() + IgoUgoJS.Config.DepRep() + '/protoculous.js.gz" charset="UTF-8"></script>');
		} else {
			document.write('<script type="text/javascript" language="javascript" src="' + IgoUgoJS.Config.StaticDomain() + IgoUgoJS.Config.DepRep() + '/protoculous.js"></script>');
		}
	}
	if (typeof(Behaviour) == 'undefined') {
		document.write('<script type="text/javascript" src="' + IgoUgoJS.Config.StaticDomain() + IgoUgoJS.Config.DepRep() + '/behaviour.js"></script>');
	}
	/*
	#####################
	IgoUgo Core
	#####################
	*/
	if (typeof(IgoUgoJS.Util) == 'undefined') {
		document.write('<script type="text/javascript" src="' + IgoUgoJS.Config.StaticDomain() + IgoUgoJS.Config.UtilRep() + '/util.js"></script>');
	}
}
IgoUgoJS.Util = new Object();

IgoUgoJS.Util.Trim = function(pString) {
	var oTemp = pString;
	var oExp = /^(\s*)([\W\w]*)(\b\s*$)/;
	if (oExp.test(oTemp)) { 
		oTemp = oTemp.replace(oExp, '$2'); 
	}
	var oExp = / +/g;
	oTemp = oTemp.replace(oExp, " ");
	if (oTemp == " ") { 
		oTemp = ""; 
	}
	return oTemp;
}

IgoUgoJS.Util.IsDefined = function(pName) {
	return (typeof(pName) != 'undefined');
}

IgoUgoJS.Util.IsFunction = function(pName) {
	return (typeof(pName) == 'function');
}

IgoUgoJS.Util.CSSClassNames = function(pAction, pElement, pClassName1, pClassName2) {
	if (null==pElement) return false;
	switch(pAction) {
		case 'swap':
			pElement.className=!IgoUgoJS.Util.CSSClassNames('check',pElement,pClassName1)?pElement.className.replace(pClassName2,pClassName1):pElement.className.replace(pClassName1,pClassName2);
			break;
		case 'add':
			if(!IgoUgoJS.Util.CSSClassNames('check',pElement,pClassName1)){
				pElement.className+=pElement.className?' '+pClassName1:pClassName1;
			}
			break;
		case 'remove':
			var oRep=pElement.className.match(' '+pClassName1)?' '+pClassName1:pClassName1;
			pElement.className=pElement.className.replace(oRep,'');
			break;
		case 'check':
			return new RegExp('\\b'+pClassName1+'\\b').test(pElement.className)
			break;
	}
}

/* 
 *  REGISTRY
 */
IgoUgoJS.Util.Registry = Class.create();
IgoUgoJS.Util.Registry.Constants = {
	KEY_PAGER:'_pager_'
}

IgoUgoJS.Util.Registry.prototype = {
	initialize: function() {
		this.mRegistry=[];
	},
	AddPager: function(pPager) {
		this.Add(IgoUgoJS.Util.Registry.Constants.KEY_PAGER + pPager.getPagerid(), pPager);
	},
	GetPager: function(pPagerid) {
		return this.Get(IgoUgoJS.Util.Registry.Constants.KEY_PAGER + pPagerid);
	},
	Add: function(pID, pObj) {
		//alert("Adding object to registry with key \"" + pID + "\"");
		this.mRegistry[pID] = pObj;
	},
	Get: function(pID) {
		//alert("Looking for object in registry with key \"" + pID + "\"");
		return this.mRegistry[pID];
	}
}

IgoUgoJS.Util.Registry.getInstance = function() {
	if (!this.mInstance) {
		//alert("Creating instance of registry");
		this.mInstance = new IgoUgoJS.Util.Registry();
	}
	return this.mInstance;
}

/* 
 * Use this method instead of Behavior.addLoadEvent().
 * This method consider the different type of browsers (netscape, IE, etc.)
 */
IgoUgoJS.Util.RegisterOnLoad = function(pFunc) {	
	if (window.attachEvent) {
		//alert("attacheEvent");
		var oResult = window.attachEvent("onload", pFunc);
	} else if (window.addEventListener) {
		//alert("addEventListener");
		window.addEventListener("load", pFunc, false);
	} else {
		//alert("onload");
		var oOldLoad = window.onload;
		if (typeof(window.onload) != 'function') {
			window.onload = pFunc;
		} else {
			window.onload = function() {
				oOldLoad();
				pFunc();
			}
		}
	}
}

/*
 * Inspect object. VERY useful with exceptions
 * Source:  Unit test from Behaviour
 */
IgoUgoJS.Util.Inspect = function(obj) {
  var info = [];

  if(typeof obj=="string" || 
     typeof obj=="number") {
    return obj;
  } else {
    for(property in obj)
      if(typeof obj[property]!="function")
        info.push(property + ' => ' + 
          (typeof obj[property] == "string" ?
            '"' + obj[property] + '"' :
            obj[property]));
  }

  return ("'" + obj + "' #" + typeof obj + 
    ": {" + info.join(", ") + "}");
}

/*
 * #####################################################
 * Logger
 * #####################################################
 */
IgoUgoJS.Util.Log = new Object();

IgoUgoJS.Util.Log.LogConfig = Class.create();
IgoUgoJS.Util.Log.LogConfig.prototype = {
	initialize: function(pName, pLevel, pAppenders) {
		this.mName=pName;
		this.mLevel=pLevel;
		this.mAppenders = pAppenders || [];
	},
	getName: function() {
		return this.mName;
	},
	getLevel: function() {
		return this.mLevel;
	},
	getAppenders: function() {
		return this.mAppenders;
	}
}

IgoUgoJS.Util.Log.Logger = Class.create();
IgoUgoJS.Util.Log.Logger.prototype = {
	initialize: function() {
		this.baseInitalize();
	},
	baseInitialize: function() {
		this.mLevel=IgoUgoJS.Util.Log.Level.INFO; // by default
		this.mAppenders=[];
	},
	getLogger: function(pName) {
		throw "Not implemented";
	},
	setLevel: function(pLevel) {
		this.mLevel=pLevel;
	},
	addAppender: function(pAppender) {
		if (!pAppender) return;
		this.mAppenders.push(pAppender);
	},
	debug: function(pMessage, pException) {
		this._processLog(IgoUgoJS.Util.Log.Level.DEBUG, pMessage, pException);
	},
	info: function(pMessage, pException) {
		this._processLog(IgoUgoJS.Util.Log.Level.DEBUG, pMessage, pException);
	},
	warn: function(pMessage, pException) {
		this._processLog(IgoUgoJS.Util.Log.Level.DEBUG, pMessage, pException);
	},
	error: function(pMessage, pException) {
		this._processLog(IgoUgoJS.Util.Log.Level.DEBUG, pMessage, pException);
	},
	fatal: function(pMessage, pException) {
		this._processLog(IgoUgoJS.Util.Log.Level.DEBUG, pMessage, pException);
	},
	_processLog: function(pLevel, pMessage, pException) {
		if (this.mLevel.isGreaterOrEqual(pLevel)) {
			return;
		} 
		var oLoggingEvent=new IgoUgoJS.Util.Log.LoggingEvent(pMessage, pLevel, pException);
		for (var i=0; i<this.mAppenders.length; i++) {
			// maybe do some checking first...
			this.mAppenders[i].doAppend(oLoggingEvent);
		}
	}
}
IgoUgoJS.Util.Log.RootLogger = Class.create();
Object.extend(IgoUgoJS.Util.Log.RootLogger.prototype, IgoUgoJS.Util.Log.Logger.prototype);
Object.extend(IgoUgoJS.Util.Log.RootLogger.prototype, {
	initialize: function(pConfigs) {
		this.load(pConfigs);
		this.baseInitialize();
	},
	load: function(pConfigs) {
		if (!pConfigs) return;
		this.mLogConfigs=[];
		var oConfig;
		for (var i=0; i<pConfigs.length; i++) {
			oConfig=pConfigs[i];
			if (oConfig.getName()=='root') {
				this.setLevel(oConfig.getLevel());
				for (var j=0; j<oConfig.getAppenders().length; j++) {
					this.addAppender(oConfig.getAppenders()[j]);
				}	
			} else {
				this.mLogConfigs[oConfig.getName()]=oConfig;
			}
		}
	},
	getLogger: function(pName) {
		var oConfig = this.mLogConfigs[pName];
		var oLogger = new IgoUgoJS.Util.Log.Logger();
		oLogger.setLevel(oConfig?oConfig.getLevel():this.getLevel());
		// if appenders specified use them
		var oAppenders;
		if (oConfig && oConfig.getAppenders() && oConfig.getAppenders().length > 0) {
			oAppenders=oConfig.getAppenders();
		} else {
			// use root ones
			oAppenders=this.mAppenders;
		}
		for (var i=0;i<oAppenders.length;i++) {
			oLogger.addAppender(oAppenders[i]);
		}
		return oLogger;
	}
});
		
IgoUgoJS.Util.Log.LogManager = new Object();
IgoUgoJS.Util.Log.LogManager.getRootLogger = function() {
	if (!this.mRootLogger) {
		this.mRootLogger=new IgoUgoJS.Util.Log.RootLogger();
	}
	return this.mRootLogger;
}
IgoUgoJS.Util.Log.LogManager.setLoggers = function(pLoggers) {
	this.mLoggers=pLoggers;
}
IgoUgoJS.Util.Log.LogManager.getLogger = function(pName) {
	var oRoot = this.getRootLogger();
	var oLogger = (pName?oRoot.getLogger(pName):oRoot);
	return oLogger;
	/*
	if (!this.mLoggers) {
		alert("Logging not yet configured. Check you are configuring the logging system before using it.");
		throw "Logging not configured";
		//return;
	}
	return this.mLoggers[pName];
	*/
}


IgoUgoJS.Util.Log.Priority = {
	ALL_INT:0,
	DEBUG_INT:1,
	INFO_INT:2,
	WARN_INT:3,
	ERROR_INT:4,
	FATAL_INT:5
}
IgoUgoJS.Util.Log.Level = Class.create();
IgoUgoJS.Util.Log.Level.prototype = {
	initialize: function(pIntLevel) {
		this.mLevel=pIntLevel;
	},
	isGreaterOrEqual: function(pLevel) {
		return (this.mLevel>=pLevel.toInt);
	},
	toInt: function() {
		return this.mLevel;
	},
	toString: function() {
		switch (this.mLevel) {
			case IgoUgoJS.Util.Log.Priority.DEBUG_INT:
				return 'debug';
			case IgoUgoJS.Util.Log.Priority.INFO_INT:
				return 'info';
			case IgoUgoJS.Util.Log.Priority.WARN_INT:
				return 'warn';
			case IgoUgoJS.Util.Log.Priority.ERROR_INT:
				return 'error';
			case IgoUgoJS.Util.Log.Priority.FATAL_INT:
				return 'fatal';
			default:
				return 'any';
		}
	}
}
IgoUgoJS.Util.Log.Level.WARN = new IgoUgoJS.Util.Log.Level(IgoUgoJS.Util.Log.Priority.WARN_INT);
IgoUgoJS.Util.Log.Level.DEBUG = new IgoUgoJS.Util.Log.Level(IgoUgoJS.Util.Log.Priority.DEBUG_INT);
IgoUgoJS.Util.Log.Level.INFO = new IgoUgoJS.Util.Log.Level(IgoUgoJS.Util.Log.Priority.INFO_INT);
IgoUgoJS.Util.Log.Level.ERROR = new IgoUgoJS.Util.Log.Level(IgoUgoJS.Util.Log.Priority.ERROR_INT);
IgoUgoJS.Util.Log.Level.FATAL = new IgoUgoJS.Util.Log.Level(IgoUgoJS.Util.Log.Priority.FATAL_INT);

IgoUgoJS.Util.Log.LoggingEvent = Class.create();
IgoUgoJS.Util.Log.LoggingEvent.prototype = {
	initialize: function(pMessage, pLevel, pException) {
		this.mMessage=pMessage;
		this.mLevel=pLevel;
		this.mException=pException;
	},
	getLevel: function() {
		return this.mLevel;
	},
	getMessage: function() {
		return this.mMessage;
	},
	getException: function() {
		return this.mException;
	}
}

/*
 * Abstract class Appender.
 * All extensions must implement "doAppend()"
 */
IgoUgoJS.Util.Log.Appender = new Object();
IgoUgoJS.Util.Log.Appender.prototype = {
	doAppend: function(pLoggingEvent) {
		throw "IgoUgoJS.Util.Log.Appender: Must implement doAppend()";	
	}
}

/*
 * Append logs to HTML element
 */
IgoUgoJS.Util.Log.ConsoleAppender = Class.create();
Object.extend(IgoUgoJS.Util.Log.ConsoleAppender.prototype, IgoUgoJS.Util.Log.Appender.prototype)
Object.extend(IgoUgoJS.Util.Log.ConsoleAppender.prototype, {
	initialize: function(pElement) {
		this.mOriginElement = pElement;
	},
	doAppend: function(pLoggingEvent) {
		if (this.mOriginElement) this.mElement = $(this.mOriginElement);
		if (!this.mElement) return;
		var oHTMLLog = this._createLog(pLoggingEvent);
		this.mElement.appendChild(oHTMLLog);
	},
	_createLog: function(pLoggingEvent) {
		var oLog=document.createElement('p');
		oLog.className='log' + pLoggingEvent.getLevel().toString();
		oLog.innerHTML=pLoggingEvent.getMessage() + (pLoggingEvent.getException()?": "+IgoUgoJS.Util.Inspect(pLoggingEvent.getException()):"");
		return oLog;
	}
});

/*
 * Display logs using the built-in "alert()" function.
 */
IgoUgoJS.Util.Log.AlertAppender = Class.create();
Object.extend(IgoUgoJS.Util.Log.AlertAppender.prototype, IgoUgoJS.Util.Log.Appender.prototype)
Object.extend(IgoUgoJS.Util.Log.AlertAppender.prototype, {
	initialize: function() {
	},
	doAppend: function(pLoggingEvent) {
		alert(pLoggingEvent.getLevel().toString() + ": " + pLoggingEvent.getMessage() + (pLoggingEvent.getException()?": "+IgoUgoJS.Util.Inspect(pLoggingEvent.getException()):""));
	}
});

/*
 * Utility to configure Logging passing an array of LogConfig
 */
IgoUgoJS.Util.Log.BasicConfigurator = new Object();
IgoUgoJS.Util.Log.BasicConfigurator.configure = function(pLogConfigs) {	
	pLogConfigs = pLogConfigs || [];
	var oRootLogger=IgoUgoJS.Util.Log.LogManager.getRootLogger();
	oRootLogger.load(pLogConfigs);
}

/*
 * Configure logging to specified level using the given HTML pElement.
 * Logs will be displayed in this pElement (using ConsoleAppender here)
 */
IgoUgoJS.Util.Log.HTMLConfigurator = new Object();
IgoUgoJS.Util.Log.HTMLConfigurator.configure = function(pLevel, pElement) {
	var oAppender = new IgoUgoJS.Util.Log.ConsoleAppender(pElement);
	var oConfig = new IgoUgoJS.Util.Log.LogConfig('root', pLevel, [oAppender]);
	IgoUgoJS.Util.Log.BasicConfigurator.configure([oConfig]);
}
// #################################################################


/*
 * Given a class name, create the instance.
 */
IgoUgoJS.Util.CreateInstance = function(pClassName) {
	IgoUgoJS.Util.EnsureNamespaces(pClassName);
	var oInst;
	eval("oInst = new " + pClassName + "()");
	return oInst;
}

/*
 * Will define missing namespaces if needed.
 * E.g. of ClassPath : "IgoUgoJS.BO.LocationBO"
 */
IgoUgoJS.Util.EnsureNamespaces = function(pClassPath) {
	var oNamespaces = pClassPath.split(".");
	var oNamespace = "";
	var oMax = oNamespaces.length -1; // last element is the actual file to load
	for (var i = 0; i < oMax; i++) {
		oNamespace += oNamespaces[i];
		//alert("working with namespace \"" + oNamespace + "\"");
		if (typeof(eval(oNamespace)) == 'undefined') {
			//alert("Namespace not yet defined...defining it.");
			eval (oNamespace + " = new Object();");
		}
		if ((i+1) < oMax) {
			oNamespace += ".";
		}
	}
}

// ##############################################################
// Imports and Loads 
// ##############################################################
/*
 * Create a JavaScript tag and append it in the Head section.
 * NB: its id will be the value of pPath
 */
IgoUgoJS.Util.CreateScript = function(pPath, pLocation) {
	//alert("Load script at " + pPath);
	//pLocation = pLocation || 'igougojs';
	var oExisting = document.getElementById(pPath);
	if (oExisting) {
		var oParent = oExisting.parentNode;
		if (oParent) {
			IgoUgoJS.Util.Log.LogManager.getLogger().debug("removing \"" + pPath + "\"");
			oParent.removeChild(oExisting);
		}
	}
	var oEl = document.createElement("script");
	oEl.defer=true;
	oEl.type='text/javascript';
	oEl.src=pPath;
	oEl.id=pPath;
	document.getElementsByTagName('head')[0].appendChild(oEl);
}

/*
 * LoadManager collects all scripts to load.
 * loadAll() will actually add the scripts to the document, but this happen only when all imports have been successful.
 */
IgoUgoJS.Util.LoadManager = Class.create();
IgoUgoJS.Util.LoadManager.prototype = {
	initialize: function() {
		this.mLoads = new Array();
	},
	add: function(pPath, pLocation) {
		this.mLoads[pPath] = pLocation;
	},
	loadAll: function() {
		for (oPath in this.mLoads) {
			if (typeof(this.mLoads[oPath]) == 'function') continue;
			IgoUgoJS.Util.Log.LogManager.getLogger().debug("Importing user script \"" + oPath + "\" at \"" + this.mLoads[oPath] + "\" (typeof value = " + typeof(this.mLoads[oPath]) + ")");
			IgoUgoJS.Util.CreateScript(oPath, this.mLoads[oPath]);			
		}
	}
}

IgoUgoJS.Util.LoadManager.getInstance = function() {
	if (!this.mInstance) {
		this.mInstance = new IgoUgoJS.Util.LoadManager();
	}
	return this.mInstance;
}

IgoUgoJS.Util.Load = function(pPath, pLocation) {
	// Add to manager
	IgoUgoJS.Util.Log.LogManager.getLogger().debug("Adding " + pPath + " from " + pLocation + " to load...");
	IgoUgoJS.Util.LoadManager.getInstance().add(pPath, pLocation);
}

/*
 * Collects all scripts that have been imported.
 * checkImports() is run every second to check all of them has been imported.
 * If so, the callback function is called.
 */
IgoUgoJS.Util.ImportManager = Class.create();
IgoUgoJS.Util.ImportManager.prototype = {
	initialize: function() {
		this.mImports=new Array();
		this.mFrequency=1;
		this.mAttempts=0;
	},
	add: function(pClassPath) {
		this.mImports.push(pClassPath);
	},
	importClass: function(pClassPath, pLocation, pAddItToList) {
		pLocation = pLocation || 'igougojs';
		//alert("Trying to import \"" + pClassPath + "\"...");
		// Defining missing namespace(s) when needed
		IgoUgoJS.Util.EnsureNamespaces(pClassPath);
		
		// Load file
		var oPath = IgoUgoJS.Config.BaseRep() + (IgoUgoJS.Config.BaseRep().indexOf("/")==(IgoUgoJS.Config.BaseRep().length-1)?"":"/");
		var oParts = pClassPath.split('.');
		if (oParts[oParts.length - 1] == '*') {
			// remove it from Imports
			for (var i = 0; i < this.mImports.length; i++) {
				if (this.mImports[i] == pClassPath) {
					this.mImports[i] = (oParts.slice(0, -1)).join('.');
					break;
				}
			}	
			oParts.pop(); // remove wildcard
			oParts.push(IgoUgoJS.Config.PackageName());
			oPath += oParts.join('/').toLowerCase() + '.js';	
		} else if (typeof(eval(pClassPath)) == 'undefined') {
			// add it to the list to check
			if (pAddItToList) this.add(pClassPath)
			// Import the file
			var oRegExp = new RegExp("\\.", "g");
			oPath += pClassPath.toLowerCase().replace(oRegExp, "/") + ".js";	
		} else {
			return;
		}
		// Here the path has been specified and the class is not defined, so we create the script for it
		IgoUgoJS.Util.Log.LogManager.getLogger().debug("Importing " + oPath + " to " + pLocation);
		IgoUgoJS.Util.CreateScript(oPath, pLocation);
	},
	checkImports: function(pCallback) {
		if (typeof(Prototype) == 'undefined') {
			// wait for prototype to be parsed
			IgoUgoJS.Util.Log.LogManager.getLogger().debug("waiting for prototype to be parsed.");
			if (this.observer) clearTimeout(this.observer);
			this.observer = setTimeout(function() { this.checkImports(pCallback) }.bind(this), this.mFrequency*10);			
		}
		var oAllImported=true;
		var oClasspath;
		for (var i = 0; i < this.mImports.length; i++) {
			oClasspath=this.mImports[i];
			IgoUgoJS.Util.Log.LogManager.getLogger().debug("Checking class \"" + oClasspath + "\" has been loaded");
			if (typeof(eval(oClasspath)) == 'undefined') {
				oAllImported=false;
				IgoUgoJS.Util.Log.LogManager.getLogger().debug("Class \"" + oClasspath + "\" needs to be imported again ");
				//this.importClass(oClasspath);
			} else {
				this.mImports.slice(i,1);
			}
		}
		if (this.observer) clearTimeout(this.observer);
		if (!oAllImported) {
			this.mAttempts++;
			if (this.mAttempts > 5) {
				//alert("Could not import classes");
				this.mAttempts=0;
			} else {
				//alert("Some imports still needs to be loaded");
				// schedule import
				this.observer = setTimeout(function() { this.checkImports(pCallback) }.bind(this), this.mFrequency*1000);
			}
		} else {
			IgoUgoJS.Util.Log.LogManager.getLogger().debug("All imports have been successfully loaded.");
			//alert("All imports have been successfully loaded.");
			if (typeof(pCallback) == 'function') {
				pCallback();
			}
		}
	}
}

IgoUgoJS.Util.ImportManager.getInstance = function() {
	if (!this.mInstance) {
		this.mInstance = new IgoUgoJS.Util.ImportManager();
	}
	return this.mInstance;
}


/*
 * Import class and fefine missing namespaces as well.
 * NB: The imports must be set in a separate file than the code itself (except for simply defining namespaces)
 * E.g. of ClassPath : "IgoUgoJS.BO.LocationBO"
 */
IgoUgoJS.Util.Import = function(pClassPath, pLocation) {
	IgoUgoJS.Util.ImportManager.getInstance().importClass(pClassPath, pLocation, true);
}

IgoUgoJS.Util.ImportLoadManager = Class.create();
IgoUgoJS.Util.ImportLoadManager.prototype = {
	initialize: function() {
		this.mLoading = false;
	},
	onLoad: function() {
		IgoUgoJS.Util.ImportManager.getInstance().checkImports(this.doLoad.bind(this));
	},
	doLoad: function() {
		IgoUgoJS.Util.LoadManager.getInstance().loadAll();
	}
}
IgoUgoJS.Util.ImportLoadManager.getInstance = function() {
	if (!this.mInstance) {
		this.mInstance = new IgoUgoJS.Util.ImportLoadManager();
	}
	return this.mInstance;
}
//Behaviour.addLoadEvent(IgoUgoJS.Util.ImportLoadManager.getInstance().onLoad.bind(IgoUgoJS.Util.ImportLoadManager.getInstance()));
IgoUgoJS.Util.RegisterOnLoad(IgoUgoJS.Util.ImportLoadManager.getInstance().onLoad.bind(IgoUgoJS.Util.ImportLoadManager.getInstance()));

// ##############################################################



IgoUgoJS.Util.DataBinder = new Object();
IgoUgoJS.Util.DataBinder.Eval = function(pObject, pProperty) {
	if (!pObject || !pProperty) return null;
	// .NET-like properties
	var oRes = pObject[pProperty];
	if (oRes) return oRes;
	// Java-like properties accessible only via getXXX() method
	oRes = eval("pObject.get" + pProperty + "()");
	return oRes;
}

// Aliases
IgoUgoJS.Load = IgoUgoJS.Util.Load;
IgoUgoJS.CreateInstance = IgoUgoJS.Util.CreateInstance;
IgoUgoJS.Import = IgoUgoJS.Util.Import;
IgoUgoJS.EnsureNamespaces  = IgoUgoJS.Util.EnsureNamespaces;
DataBinder = IgoUgoJS.Util.DataBinder;



/*
function _IgoUgoUtilImportImpl2(pPath) {
	var oPath = (pPath.indexOf("/") != 0)?"/" + pPath:pPath;
	var oContent = "<script type='text/javascript' src='" + IgoUgoJS.Config.BaseRep + pPath + "'></script>";
	new Insertion.Before('dynload', oContent);
}
*/
/*
// Different implementation of loading dynamically a script
,
	importImpl4: function(pPath) {
		// doesn't work : make the document just scripts
		document.write("<script type='text/javascript' src='" + pPath + "></script>");	
	},
	importImpl3: function(pPath) {
		// 'all' is a deprecated function according to W3C standards
		document.all.dynload.src = pPath;
	},
	importImpl2b: function(pPath) {
		// works fine !!!!!
		var oContent = "<script type='text/javascript' src='" + pPath + "'></script>";
		new Insertion.Before('dynload', oContent);		
	},
	importImpl2: function(pPath) {
		// doesn't work when loading multiple scripts (works when loading one only though)
		$('dynload').src=pPath;
	},
	importImpl: function(pPath) {		
		if (document.layers) {
			window.locations.href=url;
		} else if (document.getElementById) {
			//
			var script = document.createElement('script');
			//script.defer=true;
			script.type="text/javascript";
			script.src=pPath;
			document.getElementsByTagName('head')[0].appendChild(script);
		}
		//alert("Path is now : " + oPath);
	}
}
*/

/*
 * ######################################################
 * Request Utils
 * ######################################################
 */
IgoUgoJS.Util.Request = Class.create();

IgoUgoJS.Util.Request.prototype = {
	initialize: function(pURL) {
		this.mURL = pURL || IgoUgoJS.Config.Get('currentUrl') || window.location.toString();
		this.params=[];
		if (this.mURL.indexOf("file://") != -1) {
			// this is not a web request but a file loaded from the computer
			this.mIsWebRequest=false;
			return;
		} else {
			this.mIsWebRequest=true;
		}
		
		// Init query string
		var url=new String(this.mURL);
		
		// get rid of "#" anchor stuff
		if (url.lastIndexOf("#") > 0) {
			url = url.substring(0, url.lastIndexOf("#"));
		}
		var oQSIndex = url.indexOf("?");
		this.baseURL = url.substring(0, (oQSIndex>0)?oQSIndex:url.length) || url;
		
		if (oQSIndex == url.length || oQSIndex < 0) return;
		var oQS = url.substring(oQSIndex + 1, url.length);
		
		if (oQS.length == 0) return;
		
		var q = oQS.split('&');
		
		var oParams;
		var oReqParam;
		for (var i = 0; i < q.length; i++) {
			oParams = q[i].split('=');
			oReqParam = this.params[oParams[0]];
			//alert("ReqParam from table:" + oReqParam);
			if (!oReqParam) {
				//IgoUgoJS.Util.Log.LogManager.getLogger().debug("Adding new request param : \"" + oParams[0] + "\". Adding value \"" + oParams[1] + "\"");
				oReqParam = new IgoUgoJS.Util.RequestParam(oParams[0]);
				this.params[oParams[0]] = oReqParam;
			} else {
				//IgoUgoJS.Util.Log.LogManager.getLogger().debug("Re-using request param : \"" + oParams[0] + "\". Adding value \"" + oParams[1] + "\"");
			}
			oReqParam.addValue(oParams[1]);
		}
	},
	toBaseURL: function() {
		this.params = [];
		return this;
	},
	isWebRequest: function() {
		return this.mIsWebRequest;
	},
	getParam: function(pKey) {
		return this.params[pKey];
	},
	getValue: function(pKey, pDefault) {
		// return the first value if present
		if (!this.params[pKey] || this.params[pKey].count()==0) return pDefault;
		return this.params[pKey].getValue(0);
	},
	addParam: function(pName, pValue) {
		var oParam = this.params[pName];
		if (!oParam) {
			oParam = new IgoUgoJS.Util.RequestParam(pName);
			this.params[pName] = oParam;
		}
		oParam.addValue(pValue);
		return this;
	},
	removeParam: function(pParamName) {
		if (typeof(pParamName) == 'string') {
			this.params[pParamName] = null;
		}
		return this;
	},
	setParam: function(pParamName, pValue) {
		if (typeof(pParamName) == 'string') {
			var oParam = new IgoUgoJS.Util.RequestParam(pParamName);
			oParam.addValue(pValue);
			this.params[pParamName] = oParam;
		}
		return this;	
	},
	toString: function() {
		var oURL = this.baseURL; // should be base URL
		var oFirstPass = true;
		var oReqParam;
		for (var i in this.params) {
			oReqParam = this.params[i];
			if (!oReqParam || typeof(oReqParam) != 'object') continue;
			for (var j = 0; j < oReqParam.count(); j++) {
				if (!oFirstPass) {
					oURL += '&';
				} else {
					oURL += '?';
				}
				oFirstPass = false;
				oURL += oReqParam.getName() + '=' + oReqParam.getValue(j);	
			}	
		}
		return oURL;
	}
	
}
IgoUgoJS.Util.RequestParam = Class.create();
IgoUgoJS.Util.RequestParam.prototype = {
	initialize:function(pName) {
		this.name=pName;
		this.values=[];
	},
	getName:function() {
		return this.name;
	},
	addValue:function(pValue) {
		var oRegExp = /\+/g;
		// Return the decoded string
		var oValue = unescape(String(pValue).replace(oRegExp, " ")); 
		this.values[this.values.length]=oValue;
	},
	getValue:function(pIndex) {
		return this.values[pIndex];
	},
	count:function() {
		return this.values.length;
	}
}

IgoUgoJS.Util.Redirect = function(pURL) {
	window.location = pURL;
}

IgoUgoJS.Util.SetCookie = function(pName, pValue, pSeconds) {
	if (pSeconds) {
		var d = new Date();
		d.setTime(d.getTime() + (pSeconds * 1000));
		var expiry = '; expires=' + d.toGMTString();
	} else 
		var expiry = '';
		
	if (document.domain.indexOf('igougo') != -1) {
		var domain = '; domain=.igougo.com';
	} else
		var domain = '';
	
	document.cookie = pName + "=" + pValue + expiry + "; path=/" + domain;
};

IgoUgoJS.Util.EraseCookie = function(pName) {
	// Delete the cookie by calling "set" with a negative expiry value
	this.SetCookie(pName.replace(/^\s*|\s*$/g,""), "", -1);
	return true;
};

IgoUgoJS.Util.EraseAllCookies = function() {
	var Cookies = document.cookie.split(";");

	for ( var Cnt=0; Cnt < Cookies.length; Cnt++ ) {
		var CurCookie = Cookies[Cnt].split("=");
		if ( CurCookie[0] ) {
			this.SetCookie(CurCookie[0].replace(/^\s*|\s*$/g,""), "", -1);
		}
	}
	
	// Return "true"
	return true;
};

IgoUgoJS.Util.GetCookie = function(pName) {
	var nameEQ = pName + "=";
	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 null;
}

var requests = new Array();

if(typeof(XMLHttpRequest) == 'undefined')
var XMLHttpRequest = function()
{
	var request = null;
	try
	{
		request = new ActiveXObject('Msxml2.XMLHTTP');
	}
	catch(e)
	{
		try
		{
			request = new ActiveXObject('Microsoft.XMLHTTP');
		}
		catch(ee)
		{}
	}
	return request;
}

function ajax_stop()
{
	for(var i=0; i<requests.length; i++)
	{
		if(requests[i] != null)
			requests[i].obj.abort();
	}
}

function ajax_create_request(context)
{
	for(var i=0; i<requests.length; i++)
	{
		if(requests[i].readyState == 4)
		{
			requests[i].obj.abort();
			requests[i].context = context;
			return requests[i];
		}
	}

	var pos = requests.length;
	
	requests[pos] = Object();
	requests[pos].obj = new XMLHttpRequest();
	requests[pos].context = context;
	
	return requests[pos];
}

function ajax_request(url, data, callback, context)
{
	var request = ajax_create_request(context);
	var async = typeof(callback) == 'function';

	if(async) request.obj.onreadystatechange = function()
	{
		if(request.obj.readyState == 4 && request.obj.responseText)
			callback(new ajax_response(request));
	}
	
	request.obj.open('POST', url, async);
	request.obj.send(data);
	
	if(!async)
		return new ajax_response(request);
}

function ajax_response(request)
{
	this.request = request.obj;
	this.error = null;
	this.value = null;
	this.context = request.context;
	
	if(request.obj.status == 200)
	{
		try
		{
			this.value = object_from_json(request);
			
			if(this.value && this.value.error)
			{
				this.error = this.value.error;
				this.value = null;
			}
		}
		catch(e)
		{
			this.error = new ajax_error(e.name, e.description, e.number);
		}
	}
	else
	{
		this.error = new ajax_error('HTTP request failed with status: ' + request.obj.status, request.obj.status);
	}
	
	return this;
}

function enc(s)
{
	return s == null ? null : s.toString().replace(/\%/g, "%26").replace(/=/g, "%3D");
}

function object_from_json(request)
{
	if(request.obj.responseXML != null && request.obj.responseXML.xml != null && request.obj.responseXML.xml != '')
		return request.obj.responseXML;
	
	var r = null;	
	eval('r=' + request.obj.responseText + ';');
	return r;
}

function ajax_error(name, description, number)
{
	this.name = name;
	this.description = description;
	this.number = number;

	return this;
}

ajax_error.prototype.toString = function()
{
	return this.name + " " + this.description;
}

function json_from_object(o)
{
	if(o == null)
		return 'null';

	switch(typeof(o))
	{
		case 'object':
			if(o.constructor == Array)		// checks if it is an array [,,,]
			{
				var s = '';
				for(var i=0; i<o.length; ++i)
				{
					s += json_from_object(o[i]);

					if(i < o.length -1)
						s += ',';
				}

				return '[' + s + ']';
			}
			break;
		case 'string':
			return '"' + o.replace(/(["\\])/g, '\\$1') + '"';
		default:
			return String(o);
	}
}var ajaxVersion = '5.7.22.2';

// cached javascript
var AjaxPhotoBO = {
getUploadReport:function(pJobID,callback,context){return new ajax_request(this.url + '?_method=getUploadReport&_session=no','pJobID=' + enc(pJobID),callback, context);},
getUploadedPhotos:function(callback,context){return new ajax_request(this.url + '?_method=getUploadedPhotos&_session=r','',callback, context);},
saveUploadedPhoto:function(pPhotoID,pFileName,callback,context){return new ajax_request(this.url + '?_method=saveUploadedPhoto&_session=rw','pPhotoID=' + enc(pPhotoID)+ '\r\npFileName=' + enc(pFileName),callback, context);},
saveUploadedPhotos:function(pPhotos,callback,context){return new ajax_request(this.url + '?_method=saveUploadedPhotos&_session=rw','pPhotos=' + enc(pPhotos),callback, context);},
mapPhotosToLocationOrBusinessCard:function(pPhotoIds,pLocationID,pLocationName,pBusinessCardID,pUSBCardID,callback,context){return new ajax_request(this.url + '?_method=mapPhotosToLocationOrBusinessCard&_session=rw','pPhotoIds=' + enc(pPhotoIds)+ '\r\npLocationID=' + enc(pLocationID)+ '\r\npLocationName=' + enc(pLocationName)+ '\r\npBusinessCardID=' + enc(pBusinessCardID)+ '\r\npUSBCardID=' + enc(pUSBCardID),callback, context);},
updatePhoto:function(pPhotoID,pTitle,pDescription,pDelete,callback,context){return new ajax_request(this.url + '?_method=updatePhoto&_session=rw','pPhotoID=' + enc(pPhotoID)+ '\r\npTitle=' + enc(pTitle)+ '\r\npDescription=' + enc(pDescription)+ '\r\npDelete=' + enc(pDelete),callback, context);},
getBCardPhotos:function(pBCardID,callback,context){return new ajax_request(this.url + '?_method=getBCardPhotos&_session=no','pBCardID=' + enc(pBCardID),callback, context);},
getPhoto:function(pPhotoID,callback,context){return new ajax_request(this.url + '?_method=getPhoto&_session=no','pPhotoID=' + enc(pPhotoID),callback, context);},
url:'/ajax/IgoUgo.Ajax.BusinessObject.AjaxPhotoBO,AjaxLib.ashx'
}
function HtmlControl(id) {
	var ele = null;
	if(typeof(id) == 'object') ele = id; else ele = document.getElementById(id);
	if(ele == null) return null;
	var _o = ele.cloneNode(true);
	var _op = document.createElement('SPAN');
	_op.appendChild(_o);	
	this._source = _op.innerHTML;
}
HtmlControl.prototype.toString = function(){ return this._source; }

function HtmlControlUpdate(func, parentId) {
var f,i,ff,fa='';
var ele = document.getElementById(parentId);
if(ele == null) return;
var args = [];
for(i=0; i<HtmlControlUpdate.arguments.length; i++)
	args[args.length] = HtmlControlUpdate.arguments[i];
if(args.length > 2)
	for(i=2; i<args.length; i++){fa += 'args[' + i + ']';if(i < args.length -1){ fa += ','; }}
f = '{"invoke":function(args){return ' + func + '(' + fa + ');}}';
ff = null;eval('ff=' + f + ';');
if(ff != null && typeof(ff.invoke) == 'function')
{
	var res = ff.invoke(args);
	if(res.error != null){alert(res.error);return;}
	ele.innerHTML = res.value;
}
}
function AjaxImage(url){var img=new Image();img.src=url;return img;}
function digi(v, c){v = v + "";var n = "0000";if(v.length < c) return n.substr(0, c-v.length) + v;return v;}
function DateTime(year,month,day,hours,minutes,seconds){if(year>9999||year<1970||month<1||month>12||day<0||day>31||hours<0||hours>23||minutes<0||minutes>59||seconds<0||seconds>59)throw("ArgumentException");this.Year = year;this.Month = month;this.Day = day;this.Hours = hours;this.Minutes = minutes;this.Seconds = seconds;}
DateTime.prototype.toString = function(){return digi(this.Year,4) + digi(this.Month,2) + digi(this.Day,2) + digi(this.Hours,2) + digi(this.Minutes,2) + digi(this.Seconds,2);}
function TimeSpan(){this.Days=0;this.Hours=0;this.Minutes=0;this.Seconds=0;this.Milliseconds=0;}
TimeSpan.prototype.toString = function(){return this.Days+'.'+this.Hours+':'+this.Minutes+':'+this.Seconds+'.'+this.Milliseconds;}
function _getTable(n,e){for(var i=0; i<e.Tables.length; i++){if(e.Tables[i].Name == n)return e.Tables[i];}return null;}

var AjaxEntryBO = {
getEntryRating:function(pEntryID,pEntryType,callback,context){return new ajax_request(this.url + '?_method=getEntryRating&_session=r','pEntryID=' + enc(pEntryID)+ '\r\npEntryType=' + enc(pEntryType),callback, context);},
rateEntry:function(pEntryID,pEntryType,pRating,callback,context){return new ajax_request(this.url + '?_method=rateEntry&_session=rw','pEntryID=' + enc(pEntryID)+ '\r\npEntryType=' + enc(pEntryType)+ '\r\npRating=' + enc(pRating),callback, context);},
url:'/ajax/IgoUgo.Ajax.BusinessObject.AjaxEntryBO,AjaxLib.ashx'
}
function HtmlControl(id) {
	var ele = null;
	if(typeof(id) == 'object') ele = id; else ele = document.getElementById(id);
	if(ele == null) return null;
	var _o = ele.cloneNode(true);
	var _op = document.createElement('SPAN');
	_op.appendChild(_o);	
	this._source = _op.innerHTML;
}
HtmlControl.prototype.toString = function(){ return this._source; }

function HtmlControlUpdate(func, parentId) {
var f,i,ff,fa='';
var ele = document.getElementById(parentId);
if(ele == null) return;
var args = [];
for(i=0; i<HtmlControlUpdate.arguments.length; i++)
	args[args.length] = HtmlControlUpdate.arguments[i];
if(args.length > 2)
	for(i=2; i<args.length; i++){fa += 'args[' + i + ']';if(i < args.length -1){ fa += ','; }}
f = '{"invoke":function(args){return ' + func + '(' + fa + ');}}';
ff = null;eval('ff=' + f + ';');
if(ff != null && typeof(ff.invoke) == 'function')
{
	var res = ff.invoke(args);
	if(res.error != null){alert(res.error);return;}
	ele.innerHTML = res.value;
}
}
function AjaxImage(url){var img=new Image();img.src=url;return img;}
function digi(v, c){v = v + "";var n = "0000";if(v.length < c) return n.substr(0, c-v.length) + v;return v;}
function DateTime(year,month,day,hours,minutes,seconds){if(year>9999||year<1970||month<1||month>12||day<0||day>31||hours<0||hours>23||minutes<0||minutes>59||seconds<0||seconds>59)throw("ArgumentException");this.Year = year;this.Month = month;this.Day = day;this.Hours = hours;this.Minutes = minutes;this.Seconds = seconds;}
DateTime.prototype.toString = function(){return digi(this.Year,4) + digi(this.Month,2) + digi(this.Day,2) + digi(this.Hours,2) + digi(this.Minutes,2) + digi(this.Seconds,2);}
function TimeSpan(){this.Days=0;this.Hours=0;this.Minutes=0;this.Seconds=0;this.Milliseconds=0;}
TimeSpan.prototype.toString = function(){return this.Days+'.'+this.Hours+':'+this.Minutes+':'+this.Seconds+'.'+this.Milliseconds;}
function _getTable(n,e){for(var i=0; i<e.Tables.length; i++){if(e.Tables[i].Name == n)return e.Tables[i];}return null;}

var AjaxPhotoEntryJournalWrapperBO = {
mapPhoto:function(pEntryID,pEntryType,pIsDraft,pJournalID,pPhotoID,callback,context){return new ajax_request(this.url + '?_method=mapPhoto&_session=r','pEntryID=' + enc(pEntryID)+ '\r\npEntryType=' + enc(pEntryType)+ '\r\npIsDraft=' + enc(pIsDraft)+ '\r\npJournalID=' + enc(pJournalID)+ '\r\npPhotoID=' + enc(pPhotoID),callback, context);},
unmapPhoto:function(pEntryID,pEntryType,pIsDraft,pJournalID,pPhotoID,callback,context){return new ajax_request(this.url + '?_method=unmapPhoto&_session=r','pEntryID=' + enc(pEntryID)+ '\r\npEntryType=' + enc(pEntryType)+ '\r\npIsDraft=' + enc(pIsDraft)+ '\r\npJournalID=' + enc(pJournalID)+ '\r\npPhotoID=' + enc(pPhotoID),callback, context);},
url:'/ajax/IgoUgo.Ajax.BusinessObject.AjaxPhotoEntryJournalWrapperBO,AjaxLib.ashx'
}
function HtmlControl(id) {
	var ele = null;
	if(typeof(id) == 'object') ele = id; else ele = document.getElementById(id);
	if(ele == null) return null;
	var _o = ele.cloneNode(true);
	var _op = document.createElement('SPAN');
	_op.appendChild(_o);	
	this._source = _op.innerHTML;
}
HtmlControl.prototype.toString = function(){ return this._source; }

function HtmlControlUpdate(func, parentId) {
var f,i,ff,fa='';
var ele = document.getElementById(parentId);
if(ele == null) return;
var args = [];
for(i=0; i<HtmlControlUpdate.arguments.length; i++)
	args[args.length] = HtmlControlUpdate.arguments[i];
if(args.length > 2)
	for(i=2; i<args.length; i++){fa += 'args[' + i + ']';if(i < args.length -1){ fa += ','; }}
f = '{"invoke":function(args){return ' + func + '(' + fa + ');}}';
ff = null;eval('ff=' + f + ';');
if(ff != null && typeof(ff.invoke) == 'function')
{
	var res = ff.invoke(args);
	if(res.error != null){alert(res.error);return;}
	ele.innerHTML = res.value;
}
}
function AjaxImage(url){var img=new Image();img.src=url;return img;}
function digi(v, c){v = v + "";var n = "0000";if(v.length < c) return n.substr(0, c-v.length) + v;return v;}
function DateTime(year,month,day,hours,minutes,seconds){if(year>9999||year<1970||month<1||month>12||day<0||day>31||hours<0||hours>23||minutes<0||minutes>59||seconds<0||seconds>59)throw("ArgumentException");this.Year = year;this.Month = month;this.Day = day;this.Hours = hours;this.Minutes = minutes;this.Seconds = seconds;}
DateTime.prototype.toString = function(){return digi(this.Year,4) + digi(this.Month,2) + digi(this.Day,2) + digi(this.Hours,2) + digi(this.Minutes,2) + digi(this.Seconds,2);}
function TimeSpan(){this.Days=0;this.Hours=0;this.Minutes=0;this.Seconds=0;this.Milliseconds=0;}
TimeSpan.prototype.toString = function(){return this.Days+'.'+this.Hours+':'+this.Minutes+':'+this.Seconds+'.'+this.Milliseconds;}
function _getTable(n,e){for(var i=0; i<e.Tables.length; i++){if(e.Tables[i].Name == n)return e.Tables[i];}return null;}

var AjaxPhotoService = {
trackPhotoUpload:function(pTotalPhotos,callback,context){return new ajax_request(this.url + '?_method=trackPhotoUpload&_session=r','pTotalPhotos=' + enc(pTotalPhotos),callback, context);},
getPhoto:function(pPhotoID,pFetches,callback,context){return new ajax_request(this.url + '?_method=getPhoto&_session=no','pPhotoID=' + enc(pPhotoID)+ '\r\npFetches=' + enc(pFetches),callback, context);},
translateEntryID:function(pEntryID,pReviewType,callback,context){return new ajax_request(this.url + '?_method=translateEntryID&_session=no','pEntryID=' + enc(pEntryID)+ '\r\npReviewType=' + enc(pReviewType),callback, context);},
getPhotoDisplays:function(pKeywords,pFetches,pFilters,pSort,pFrom,pTo,callback,context){return new ajax_request(this.url + '?_method=getPhotoDisplays&_session=no','pKeywords=' + enc(pKeywords)+ '\r\npFetches=' + enc(pFetches)+ '\r\npFilters=' + enc(pFilters)+ '\r\npSort=' + enc(pSort)+ '\r\npFrom=' + enc(pFrom)+ '\r\npTo=' + enc(pTo),callback, context);},
getPhotos:function(pKeywords,pFetches,pFilters,pSort,pFrom,pTo,callback,context){return new ajax_request(this.url + '?_method=getPhotos&_session=r','pKeywords=' + enc(pKeywords)+ '\r\npFetches=' + enc(pFetches)+ '\r\npFilters=' + enc(pFilters)+ '\r\npSort=' + enc(pSort)+ '\r\npFrom=' + enc(pFrom)+ '\r\npTo=' + enc(pTo),callback, context);},
getMyPhotos:function(pKeywords,pFetches,pFilters,pSort,pFrom,pTo,callback,context){return new ajax_request(this.url + '?_method=getMyPhotos&_session=r','pKeywords=' + enc(pKeywords)+ '\r\npFetches=' + enc(pFetches)+ '\r\npFilters=' + enc(pFilters)+ '\r\npSort=' + enc(pSort)+ '\r\npFrom=' + enc(pFrom)+ '\r\npTo=' + enc(pTo),callback, context);},
getReviewPhotos:function(pReviewID,pReviewType,pIsDraft,pFrom,pTo,callback,context){return new ajax_request(this.url + '?_method=getReviewPhotos&_session=no','pReviewID=' + enc(pReviewID)+ '\r\npReviewType=' + enc(pReviewType)+ '\r\npIsDraft=' + enc(pIsDraft)+ '\r\npFrom=' + enc(pFrom)+ '\r\npTo=' + enc(pTo),callback, context);},
getMyReviewPhotos:function(pReviewID,callback,context){return new ajax_request(this.url + '?_method=getMyReviewPhotos&_session=no','pReviewID=' + enc(pReviewID),callback, context);},
unlinkPhotoFromReview:function(pReviewID,pPhotoID,callback,context){return new ajax_request(this.url + '?_method=unlinkPhotoFromReview&_session=r','pReviewID=' + enc(pReviewID)+ '\r\npPhotoID=' + enc(pPhotoID),callback, context);},
mapPhotoToReview:function(pReviewID,pPhotoID,callback,context){return new ajax_request(this.url + '?_method=mapPhotoToReview&_session=r','pReviewID=' + enc(pReviewID)+ '\r\npPhotoID=' + enc(pPhotoID),callback, context);},
mapPhotoToJournalReview:function(pReviewID,pPhotoID,pJournalID,callback,context){return new ajax_request(this.url + '?_method=mapPhotoToJournalReview&_session=r','pReviewID=' + enc(pReviewID)+ '\r\npPhotoID=' + enc(pPhotoID)+ '\r\npJournalID=' + enc(pJournalID),callback, context);},
url:'/ajax/IgoUgo.Ajax.Services.AjaxPhotoService,AjaxServicesLib.ashx'
}
function HtmlControl(id) {
	var ele = null;
	if(typeof(id) == 'object') ele = id; else ele = document.getElementById(id);
	if(ele == null) return null;
	var _o = ele.cloneNode(true);
	var _op = document.createElement('SPAN');
	_op.appendChild(_o);	
	this._source = _op.innerHTML;
}
HtmlControl.prototype.toString = function(){ return this._source; }

function HtmlControlUpdate(func, parentId) {
var f,i,ff,fa='';
var ele = document.getElementById(parentId);
if(ele == null) return;
var args = [];
for(i=0; i<HtmlControlUpdate.arguments.length; i++)
	args[args.length] = HtmlControlUpdate.arguments[i];
if(args.length > 2)
	for(i=2; i<args.length; i++){fa += 'args[' + i + ']';if(i < args.length -1){ fa += ','; }}
f = '{"invoke":function(args){return ' + func + '(' + fa + ');}}';
ff = null;eval('ff=' + f + ';');
if(ff != null && typeof(ff.invoke) == 'function')
{
	var res = ff.invoke(args);
	if(res.error != null){alert(res.error);return;}
	ele.innerHTML = res.value;
}
}
function AjaxImage(url){var img=new Image();img.src=url;return img;}
function digi(v, c){v = v + "";var n = "0000";if(v.length < c) return n.substr(0, c-v.length) + v;return v;}
function DateTime(year,month,day,hours,minutes,seconds){if(year>9999||year<1970||month<1||month>12||day<0||day>31||hours<0||hours>23||minutes<0||minutes>59||seconds<0||seconds>59)throw("ArgumentException");this.Year = year;this.Month = month;this.Day = day;this.Hours = hours;this.Minutes = minutes;this.Seconds = seconds;}
DateTime.prototype.toString = function(){return digi(this.Year,4) + digi(this.Month,2) + digi(this.Day,2) + digi(this.Hours,2) + digi(this.Minutes,2) + digi(this.Seconds,2);}
function TimeSpan(){this.Days=0;this.Hours=0;this.Minutes=0;this.Seconds=0;this.Milliseconds=0;}
TimeSpan.prototype.toString = function(){return this.Days+'.'+this.Hours+':'+this.Minutes+':'+this.Seconds+'.'+this.Milliseconds;}
function _getTable(n,e){for(var i=0; i<e.Tables.length; i++){if(e.Tables[i].Name == n)return e.Tables[i];}return null;}


function gblPopupPage(URL, l, t, w, h){
	w=Math.min(w, screen.width);
	h=Math.min(h, screen.height);
	var windowprops = "location=no,scrollbars=no,menubars=no,toolbars=no,resizable=no" + ",left=" + l + ",top=" + t + ",width=" + w + ",height=" + h;
	popup = window.open(URL, "MenuPopup", windowprops);
	popup.focus();
}

function gblResizePopupPage(URL, l, t, w, h){
	w=Math.min(w, screen.width);
	h=Math.min(h, screen.height);
	var windowprops = "location=no,scrollbars=no,menubar=no,toolbar=no,resizable=yes" + ",left=" + l + ",top=" + t + ",width=" + w + ",height=" + h;
	popup = window.open(URL, "MenuPopup", windowprops);
	popup.focus();
}

function gblResizePopupPageScroll(URL, l, t, w, h){
	w=Math.min(w, screen.width);
	h=Math.min(h, screen.height);
	var windowprops = "location=no,scrollbars=yes,menubar=no,toolbar=no,resizable=yes" + ",left=" + l + ",top=" + t + ",width=" + w + ",height=" + h;
	popup = window.open(URL, "MenuPopup", windowprops);
	popup.focus();
}

// This function takes no positioning params, it is *always* a centered dialog
function gblModalPopupPage(URL, w, h){
         /*if (window.showModalDialog) { // IE
            var left = (screen.availWidth - w)/2;
	    var top = (screen.availHeight - h)/2;
            var dialogArguments = new Object();
            var _R = window.showModalDialog(URL, dialogArguments, "dialogWidth="+w+"px;dialogHeight="+h+"px;scroll=no;status=no;");
         } else { // NS*/
    	    var l = (screen.width-w)/2;
	    var t = (screen.height-h)/2;
            popup = window.open(URL, "MenuPopup", "modal=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,dependent=yes,left="+l+",top="+t+",width="+w+",height="+h);
            popup.focus();
         //}
}

function gblResizeablePopupPage(URL, l, t, w, h){
	w=Math.min(w, screen.width);
	h=Math.min(h, screen.height);
	var windowprops = "location=no,scrollbars=yes,menubar=yes,toolbar=yes,resizable=yes" + ",left=" + l + ",top=" + t + ",width=" + w + ",height=" + h;
	popup = window.open(URL, "MenuPopup", windowprops);
	popup.focus();
}

function gblPopunderPage(URL, l, t, w, h){
	w=Math.min(w, screen.width);
	h=Math.min(h, screen.height);
	var windowprops = "location=no,scrollbars=no,menubars=no,toolbars=no,resizable=no,left=" + l + ",top=" + t + ",width=" + w + ",height=" + h;
	popup = window.open(URL,"sweepstakes",windowprops);
	popup.blur();
}

function gblContentRatingInfo(pTitle) {
	var oWin = window.open('/global/html/contentratinginfo.html?title=' + pTitle, "win", "toolbar=no,location=no,width=300,height=150,menubar=no,resizable=no,status=no,scrollbars=no");
}

function gblEditorRatingInfo(pTitle) {
	var oWin = window.open('/global/html/editorratinginfo.html?title=' + pTitle, "win", "toolbar=no,location=no,width=300,height=150,menubar=no,resizable=no,status=no,scrollbars=no");
}
function glbSoftPopUpTrips(pCardID, pWidth, pHeight){
    if( typeof SoftPopup == "undefined"){ return;}
    var frameTemplate = new Template('<iframe id="BCIframe" src="#{src}" frameBorder="0" width="#{width}" scrolling="auto" height="#{height}"></iframe>');
    var oHTML = frameTemplate.evaluate({src: "/plan/add-to-trip.aspx?businesscardid=" + pCardID, width: pWidth, height: pHeight });
    TripsPop = new SoftPopup();
    TripsPop.modalDiv= "<div id='ModalWindow' class='add-bizcard softpopup'></div>";
    TripsPop.show(oHTML);      
    
    
}
/*************************** Cheer Rating **************************/

var TutorialCookieValue = 'HidePopup';

function CommunityRatingCallBack(pReturn){
    if($(pReturn.value)){
        displaySuccessMessage(0,pReturn.value);
    }
}

function displaySuccessMessage(pContentID,pControlID){
    if (pContentID > 0) {
        $("redFlag_" + pContentID).up().update("<li><a class='ic i-flag-valid'>Thanks! We'll check it out.</a></li>");
    }else{
        $(pControlID).up().update("<li><a class='ic i-cheer-valid'>Thanks! We applaud your cheer.</a></li>");
    }
}

function applyCommunityRating(pElement){
    oContentType = $(pElement).getAttribute('contenttype');
    oTargetId = $(pElement).getAttribute('targetid');
	
	if (displayCheerPopup()) {
		gblModalPopupPage('/best_of/cheer.aspx', 520, 240);
	}
	
	CommunityRatingBO.rate(oTargetId,oContentType, CommunityRatingCallBack);
	saveCookie(oTargetId,oContentType,false);
}

// Display the cheer tutorial for users that have not explicitly turned it off
function displayCheerPopup() {
	var oCookieValue = IgoUgoJS.Util.GetCookie('igorate_tutorial');
	if (oCookieValue && oCookieValue.indexOf(TutorialCookieValue) > -1) {
		return false;
	}
	return true;
}

function saveCookie(pTargetId, pContentType, pIsRedFlag){
    CommunityRatingBO.saveCookie(pTargetId,pContentType, pIsRedFlag);
} 

/***************** /Cheer Rating ***************************************/

// cached javascript
var CommunityRatingBO = {
rate:function(pID,pContentType,callback,context){return new ajax_request(this.url + '?_method=rate&_session=r','pID=' + enc(pID)+ '\r\npContentType=' + enc(pContentType),callback, context);},
getRatingStatus:function(pId,pContentType,callback,context){return new ajax_request(this.url + '?_method=getRatingStatus&_session=r','pId=' + enc(pId)+ '\r\npContentType=' + enc(pContentType),callback, context);},
saveCookie:function(pID,pContentType,pIsRedFlag,callback,context){return new ajax_request(this.url + '?_method=saveCookie&_session=no','pID=' + enc(pID)+ '\r\npContentType=' + enc(pContentType)+ '\r\npIsRedFlag=' + enc(pIsRedFlag),callback, context);},
getBestOfReviews:function(pMode,pTo,pFrom,callback,context){return new ajax_request(this.url + '?_method=getBestOfReviews&_session=no','pMode=' + enc(pMode)+ '\r\npTo=' + enc(pTo)+ '\r\npFrom=' + enc(pFrom),callback, context);},
getBestOfJournals:function(pMode,pTo,pFrom,callback,context){return new ajax_request(this.url + '?_method=getBestOfJournals&_session=no','pMode=' + enc(pMode)+ '\r\npTo=' + enc(pTo)+ '\r\npFrom=' + enc(pFrom),callback, context);},
getBestOfPhotos:function(pMode,pTo,pFrom,callback,context){return new ajax_request(this.url + '?_method=getBestOfPhotos&_session=no','pMode=' + enc(pMode)+ '\r\npTo=' + enc(pTo)+ '\r\npFrom=' + enc(pFrom),callback, context);},
getBestOfExperiences:function(pMode,pTo,pFrom,callback,context){return new ajax_request(this.url + '?_method=getBestOfExperiences&_session=no','pMode=' + enc(pMode)+ '\r\npTo=' + enc(pTo)+ '\r\npFrom=' + enc(pFrom),callback, context);},
url:'/ajax/IgoUgo.Ajax.BusinessObject.CommunityRatingBO,AjaxLib.ashx'
}
function HtmlControl(id) {
	var ele = null;
	if(typeof(id) == 'object') ele = id; else ele = document.getElementById(id);
	if(ele == null) return null;
	var _o = ele.cloneNode(true);
	var _op = document.createElement('SPAN');
	_op.appendChild(_o);	
	this._source = _op.innerHTML;
}
HtmlControl.prototype.toString = function(){ return this._source; }

function HtmlControlUpdate(func, parentId) {
var f,i,ff,fa='';
var ele = document.getElementById(parentId);
if(ele == null) return;
var args = [];
for(i=0; i<HtmlControlUpdate.arguments.length; i++)
	args[args.length] = HtmlControlUpdate.arguments[i];
if(args.length > 2)
	for(i=2; i<args.length; i++){fa += 'args[' + i + ']';if(i < args.length -1){ fa += ','; }}
f = '{"invoke":function(args){return ' + func + '(' + fa + ');}}';
ff = null;eval('ff=' + f + ';');
if(ff != null && typeof(ff.invoke) == 'function')
{
	var res = ff.invoke(args);
	if(res.error != null){alert(res.error);return;}
	ele.innerHTML = res.value;
}
}
function AjaxImage(url){var img=new Image();img.src=url;return img;}
function digi(v, c){v = v + "";var n = "0000";if(v.length < c) return n.substr(0, c-v.length) + v;return v;}
function DateTime(year,month,day,hours,minutes,seconds){if(year>9999||year<1970||month<1||month>12||day<0||day>31||hours<0||hours>23||minutes<0||minutes>59||seconds<0||seconds>59)throw("ArgumentException");this.Year = year;this.Month = month;this.Day = day;this.Hours = hours;this.Minutes = minutes;this.Seconds = seconds;}
DateTime.prototype.toString = function(){return digi(this.Year,4) + digi(this.Month,2) + digi(this.Day,2) + digi(this.Hours,2) + digi(this.Minutes,2) + digi(this.Seconds,2);}
function TimeSpan(){this.Days=0;this.Hours=0;this.Minutes=0;this.Seconds=0;this.Milliseconds=0;}
TimeSpan.prototype.toString = function(){return this.Days+'.'+this.Hours+':'+this.Minutes+':'+this.Seconds+'.'+this.Milliseconds;}
function _getTable(n,e){for(var i=0; i<e.Tables.length; i++){if(e.Tables[i].Name == n)return e.Tables[i];}return null;}
