// does the user still have MSIE 6?
// TODO: do not user jQuery for that,
// because these properties are deprecated
var msie6 = $.browser.msie && $.browser.version < 7;
var msie = $.browser.msie;

if (console === undefined) {
	var console = jQuery("<div style='background-color: white; position: absolute; top: 0; left: 0;' />");
	jQuery(document).ready(function() {
		jQuery("body").append(console);
	});
	console.log = function(txt) {
		console.html(console.html() + txt + "<br />");
	}
}

// close flash intro
// this function is called from the flash intro on the home page
function closeSWF() {
	jQuery("#teaser-flash-container").remove();
	jQuery("#teaser li.menu").show();
};

/*
 * jQuery i18n plugin
 * @requires jQuery v1.1 or later
 *
 * Examples at: http://recurser.com/articles/2008/02/21/jquery-i18n-translation-plugin/
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Based on 'javascript i18n that almost doesn't suck' by markos
 * http://markos.gaivo.net/blog/?p=100
 *
 * Revision: $Id$
 * Version: 1.0.0  Feb-10-2008
 */
 (function($) {
/**
 * i18n provides a mechanism for translating strings using a jscript dictionary.
 *
 */
	var i18n_dict = {};

/*
 * i18n property list
 */
$.i18n = {
	
/**
 * setDictionary()
 * Initialise the dictionary and translate nodes
 *
 * @param property_list i18n_dict : The dictionary to use for translation
 */
	setDictionary: function(i18n_dict_param) {
		i18n_dict = i18n_dict_param;
	},
	
/**
 * _()
 * The actual translation function. Looks the given string up in the 
 * dictionary and returns the translation if one exists. If a translation 
 * is not found, returns the original word
 *
 * @param string str : The string to translate 
 * @param property_list params : params for using printf() on the string
 * @return string : Translated word
 *
 */
	_: function (str, params) {
		var transl = str;
		if (i18n_dict && i18n_dict[str]) {
			transl = i18n_dict[str];
		}
		return this.printf(transl, params);
	},
	
/**
 * toEntity()
 * Change non-ASCII characters to entity representation 
 *
 * @param string str : The string to transform
 * @return string result : Original string with non-ASCII content converted to entities
 *
 */
	toEntity: function (str) {
		var result = '';
		for (var i=0;i<str.length; i++) {
			if (str.charCodeAt(i) > 128)
				result += "&#"+str.charCodeAt(i)+";";
			else
				result += str.charAt(i);
		}
		return result;
	},
	
/**
 * stripStr()
 *
 * @param string str : The string to strip
 * @return string result : Stripped string
 *
 */
 	stripStr: function(str) {
		return str.replace(/^\s*/, "").replace(/\s*$/, "");
	},
	
/**
 * stripStrML()
 *
 * @param string str : The multi-line string to strip
 * @return string result : Stripped string
 *
 */
	stripStrML: function(str) {
		// Split because m flag doesn't exist before JS1.5 and we need to
		// strip newlines anyway
		var parts = str.split('\n');
		for (var i=0; i<parts.length; i++)
			parts[i] = stripStr(parts[i]);
	
		// Don't join with empty strings, because it "concats" words
		// And strip again
		return stripStr(parts.join(" "));
	},

/*
 * printf()
 * C-printf like function, which substitutes %s with parameters
 * given in list. %%s is used to escape %s.
 *
 * Doesn't work in IE5.0 (splice)
 *
 * @param string S : string to perform printf on.
 * @param string L : Array of arguments for printf()
 */
	printf: function(S, L) {
		if (!L) return S;

		var nS = "";
		var tS = S.split("%s");

		for(var i=0; i<L.length; i++) {
			if (tS[i].lastIndexOf('%') == tS[i].length-1 && i != L.length-1)
				tS[i] += "s"+tS.splice(i+1,1)[0];
			nS += tS[i] + L[i];
		}
		return nS + tS[tS.length-1];
	}

};


})(jQuery);

/*
 * jQuery Juwimm plugins
 * @requires jQuery v1.3 or later
 *
 */
(function($) {

/**
 * replaceButtons()
 * replaces the button elements in result by <a> elements that are better stylable
 * and adds behaviors to them so they will be usable like 
 *
 */
$.fn.replaceButtons = function() {
	return this.each(function() {
		$(this).find("input[type='submit'], input[type='reset'], input[type='button'], button").each(function() {
			// find all buttons inside the matched elements		
			var t = $(this)
			
			// hide button and insert <a> tag after that is better stylable and add click behavior
			t.hide().after($('<a href="#" class="gui-btn"><span>' + t.val() + '</span></a>')
				.click(function() { t.trigger("click"); if(msie6) { $(this).blur(); }; return false; }));
			
			// do some css fixeing to handle buggy :hover, :active, :focus events in MSIE 
			if (msie) {
				t.next().attr("class", "gui-btn-normal")
					.focus(function() { $(this).attr("class", "gui-btn-focus"); })
					.blur(function() { $(this).attr("class", "gui-btn-normal"); })
					.mousedown(function() { $(this).attr("class", "gui-btn-active"); })
					.mouseup(function() { $(this).attr("class", "gui-btn-normal"); });
			}
		});
	});
};


/**
 * destroyForm()
 * disable all forms in matched elements
 * warning! this cannot be undone
 */
$.fn.destroyForm = function() {
	return this.each(function() {		
		var t = $(this);
		
		// disable all form elements in result
		t.find("input, select, textarea").attr("disabled", "disabled");
		
		// disable also all buttons that have been replaced by graphical versions
		t.find("a.gui-btn").addClass("gui-btn-disabled").unbind().click(function() { return false; });
	});
};

/**
 * initFormBehaviors()
 * initialize form, that means initalize it in the way that is needed for rebismart website
 * - hides submit buttons that are not supposed to show up by using $.fn.hideInvisibleSubmits()
 * - replaces buttons by using $.fn.replaceButtons()
 * - adds :focus and :hover fixes to MSIE 6
 */
$.fn.initFormBehaviors = function() {
	return this.each(function() {
			var t = $(this);
			
			// replace all buttons by graphical versions, but only if we are not in print mode
			if ($("body").attr("id") != "print") {
				t.replaceButtons();
			}
			
			if (msie6) {
				$("input[type=text], input[type=password], textarea, select", t)
					.focus(function() { $(this).addClass("input-focus"); })
					.blur(function() { $(this).removeClass("input-focus"); });
			}
	});
};

/**
 * getScrollbarWidth();
 * determine the actual scrollbar width of user's browser
 *
 */
$.getScrollbarWidth = function() {
    
    // create hidden test element with contained <div> and append to body
    var testElm = $('<div />').css({
    	width: 50, height: 50,
    	overflow: "hidden",	position: "absolute",
    	top: -1000,	left: -1000
    }).append($("<div />").css("height", 100));
    $('body').append(testElm);
    
    // get the inner element's width
    var widthBefore = $(testElm).find("div").innerWidth();
    
    // now set outer element's overflow to scroll, scrollbars should appear
    testElm.css("overflow-y", "scroll");
    
    // inner div is now less wide than before, get the new width!
    var widthAfter = $(testElm).find("div").innerWidth();
    $(testElm).remove();
    
    // calculate the difference and return it    
    return (widthBefore - widthAfter);
}

/**
 * faqList()
 * turns a list, usually a <dl> list, which uses <dt> for questions an <dd> for answers
 *
 * Options:
 * - questionTags string: A selector for the question tags. Any jQuery selector possible, you can also use span.question, div.title, etc.
 * - answerTags string: A selector for answer tags
 * - expandedId int: An index value, if set the answer with this index will be expanded on page load. 
 * - animationSpeed: Time in ms that is needed to expand/collapse an answer
 * 
 * @options object An object, containing key:"value"-pairs 
 *
 */
 
$.fn.faqList = function(options) {
	
	var settings = $.extend({
		questionTags: "dt",
		answerTags: "dd",
		expandedId: false,
		animationSpeed: 400
	}, options);


	this.each(function(i, v) {
		var l = $(this);
		   
		if (settings.expandedId != false) {
			// if an expanded id is given, hide answers except for this one
			var answers = l.find(settings.answerTags).not(":eq(" + settings.expandedId + ")").hide();
		} else {
			// if no expanded id is given, simply hide all answers
			var answers = l.find(settings.answerTags).hide();
		}
		
		l.find(settings.questionTags).each(function(i, v) {
			// add a link tag to all matched questions
			$(this).find("a").click(function() { //dont destroy anything
				// add toggle functionality
				l.find(settings.answerTags + ":visible").slideUp(settings.animationSpeed);
				if (!answers.eq(i).is(":visible")) {
					answers.eq(i).slideDown(settings.animationSpeed);
					webtrendsCallFaq($(this).text());
				}
				return false;
			});
		});
	});
};

function webtrendsCallFaq (question)    {
    var myUrl = window.location.href;  
    meinStr = myUrl.match(/^https?:\/\/[a-zA-Z0-9.-]+\/[a-z]{2}(.*)$/)[1];
    var cutedUrl = meinStr.substring(1, meinStr.lastIndexOf('.html'));  
	dcsMultiTrack('DCS.dcsuri', cutedUrl +'/'+ encodeURI(question.toLowerCase()), 'WT.ti', encodeURI(question), 'WT.dl', '21');
}

/**
 * AjaxPopup()
 * class to create a popup using boxy and load content via ajax request
 * Options should be self-explaining
 *
 * @param options object An object, containing settings for AjaxPopup class
 */
var AjaxPopup = function(options) {
	
	var self = this;
	
	// SETTINGS
		
	var settings = $.extend({
		// popup and ajax related options
		url: "",
		cache: false,
		autoStart: true,
		
		// callback functions for handling answer
		success: null,
		error: null,	

		// boxy related options
		modal: true,
		title: "&#160;",
		autoShowContent: true,
		
		// eye candy and css classes
		contentClass: "boxy-content",
		animationSpeed: 250,
		loadingOpacity: 0.3, 
		
		// fields for form requests,
		type: "get",
		date: null
		
	}, options);
	
	// INTERNALS
	
	// create boxy object and DOM nodes
	var boxy = this.boxy = new Boxy("<div class='" + settings.contentClass + "'><div class='boxy-loader'></div><div class='boxy-content-wrapper'></div></div>",
		{title: settings.title, closeText: $.i18n._("js.closeWindow"), modal: settings.modal, unloadOnHide: true, show: false});
	
	// boxy content, only used internal 
	var boxyContent = boxy.getContent();
	
	// hide the boxy loading GIF
	var loader = boxyContent.find(".boxy-loader").hide();
	
	// all content will be set using useContent variable instead of the original
	// boxy content element
	var userContent = boxyContent.find(".boxy-content-wrapper");
	
	// background disappears in MSIE6 when usign opacity on userContent element
	// conclusion: MSIE6 users won't see faded content, instead is is set invisible  
	if (msie6) {
		userContent.css("visibility", "hidden");
	} else {
		userContent.css("opacity", 0);
	}
	
	// PUBLIC METHODS
	
	// re-set options
	this.setOptions = function(options) {
		$.extend(settings, options);
		return self;
	};
	
	// get Value of a single option
	this.getOption = function(name) {
		return settings[name];
	};
	
	// sets Value of a single option
	this.setOption = function(name, value) {
		settings[name] = value;
		return self;
	};
	
	// blend out content on loading
	// for MSIE6 users, turn everything to white, for all others fade content
	this.blendOut = function(callback) {
		if (msie6) {
			userContent.css("visibility", "hidden");
			if ($.isFunction(callback)) {
				callback();
			}
		} else {
			userContent.animate({opacity: settings.loadingOpacity}, settings.animationSpeed, "linear", callback);
		}
	};
	
	// blend in content after loading
	this.blendIn = function(callback, centerAfter) {
		if (msie6) {
			userContent.css("visibility", "visible");
			if ($.isFunction(callback)) {
					callback();
			}
		} else {
			userContent.animate({opacity: 1}, settings.animationSpeed, "linear", function() {
				if (msie && !msie6) userContent.css("filter", ""); // bug fix for msie to prevent messed up text rendering cause by alpha() filter.
				if ($.isFunction(callback)) {
					callback();
				}
			});
		}
	};
	
	// loader fadeIn and fadeOut
	this.showLoader = function(callback) {
		if (!msie6) {
			loader.fadeIn(250, callback);
		} else {
			loader.show();
			if ($.isFunction(callback)) {
				callback();
			}
		}
	};
	
	this.hideLoader = function(callback) {
		if (!msie6) {
			loader.fadeOut(250, callback);
		} else {
			loader.hide();
			if ($.isFunction(callback)) {
				callback();
			}
		}
	};
	
	// starts or restarts the ajax request
	this.startRequest = function() {
		if (!boxy.isVisible()) {
			// if boxy is invisible, show it when loading content.
			boxy.show();
		}
		
		var ajaxFunction = function() {
			self.showLoader(function() {
				// create ajax request after showing loader
				$.ajax({
						url: settings.url,
						type: settings.type,
						data: settings.data,
						
						// when the request had success
						success: function(data, textStatus) {
							self.hideLoader(function() {
								// when a callback function is set, use it, otherwise just write server's answer into userContent element
								if ($.isFunction(settings.success)) {
									settings.success(data, textStatus, userContent);
									if (settings.autoShowContent) {
										self.blendIn();
									}				
								} else {
									userContent.html(data);
									self.blendIn();
								}
							});
						},
						
						// if an error occured
					
						error: function (XMLHttpRequest, textStatus, errorThrown) {			
							self.hideLoader(function() {
								// you can defne own error messages, but usually it's enough to use the default function which
								// tells the user that there's been a connection error or sth. else
								if ($.isFunction(settings.error)) {
									settings.error(XMLHttpRequest, textStatus, errorThrown, userContent);
									if (settings.autoShowContent) {
										self.blendIn();
									}				
								} else {
									// throw error message and give user the possibility to try again
									userContent.html($("<h1 />").html($.i18n._("ajax.error")))
										.append("<p>" + $.i18n._("ajax.errorMessage") + "</p><p><a href='#' class='try-again gui-btn'><span>" + $.i18n._("ajax.tryAgain") + "</span></a></p>")
										.find("a.try-again").click(function() { self.startRequest(); return false; });
									self.blendIn();
								}
							});
						},	
						dataType: "html",
						cache: settings.cache
				});
			});
		};
		
		this.blendOut(ajaxFunction);
	};
	
	// THE REST
	
	if (settings.autoStart) {
		// start automatically (default is true)
		this.startRequest();
	}
};

/**
 * createAjaxPopup()
 * Wrapper function for creating an Ajax popup
 *
 * @param options object An object, containing settings for AjaxPopup class
 * @return object a new AjaxPopup object
 */
$.createAjaxPopup = function(options) {
	return new AjaxPopup(options);
}

/**
 * AjaxRegistration()
 * Ajax Registration class for RebiSmart
 *
 * @param options object An object, containing settings
 */
var AjaxRegistration = function(options) {
	
	var self = this;
	
	// SETTINGS
	var settings = $.extend({
		formUrl: "#"
	}, options);
	
	// INITIALIZATION
	// create AjaxPopup object for displaying registration forms and stuff
	var p = $.createAjaxPopup({
		url: settings.formUrl,
		autoStart: false,
		autoShowContent: false
	});
	
	// PRIVATE METHODS
	// handle form submits inside the ajax window
	var handleFormSubmit = function() {
		var f = p.boxy.getContent().find('form'); 
		if (f.attr("action") != "") {
			// only change request url if form has an action attribute use the same URL used on Request before.
			p.setOption("url", f.attr("action"));
		}
		
		// serialize form inputs and set request type to post when submitting forms
		p.setOptions({
			data: f.serialize(),
			type: "post"
		});
		
		// destroy old form when sending data
		p.boxy.getContent().destroyForm();
		
		p.startRequest();
		
		// return false because this function is used as callback for DOM elements		
		return false;
	};	
	
	var ajaxSuccess = function(data, textStatus, content) {
		
		var d = $(data);
		
		if ($("#statusMessage", d).size() > 0) {
			// if there is an element with id "statusMessage", concat the text chunks that give us the link to another page
			// and start another request to load that page 
						
			$(document.body).append($("#contentwrapperLink", d).html());
			
			p.setOptions({
				url: $("#contentwrapperLink", d).attr("href") + "?statusMessage=" + $("#statusMessage", d).html(),
				type: "get"
			});
			
			p.startRequest();

		} else if ($("#sch_afterForm_reb", d).size() > 0 ) {
			// if we are on an afterForm page, just inject content, blend in and center boxy window on screen 
			content.html($("#sch_afterForm_reb", d).html());
			p.blendIn();
			p.boxy.animatedCenter();
			
		} else {
			// if none of the above is true, inject html and initialize form behaviors, attach events, etc.
			
			var f = content.html(data).find("form").initFormBehaviors().submit(handleFormSubmit);
			if(f.size() > 0) {
				// if answer page has any forms
				    dcsMultiTrack('WT.si_n', 'CountryReminder', 'WT.si_x', '1');
				if (msie) {
					// fix missing form submits when pressing enter in MSIE
					f.find("input[type='text'], input[type='password']").keydown(function (e) {
						if(e.keyCode == 13) {
							$(this).parents("form:first").submit();
							return false
						}
					});
				}
				
				// attach submit handler to submit button
				f.find("input[type=submit]").click(handleFormSubmit);
			} else {
				var link = settings.formUrl.match(/externalLink=([^&]+)/);
				var noButtons = settings.formUrl.match(/externalLink=noButtons/);	
				var selectedCountry = settings.formUrl.match(/selectedCountry=([^&]+)/);
				
				if (link != null && link[1] !== undefined) {
					// country page exists.
					// add question answers at the bottom of the page
					content.addClass("boxy-content-available");					
										
					content.find("h2").append('<span class="selected-country"> '+selectedCountry[1]+'</span>');
					if(!noButtons){
					    content.append('<div class="answers"><input type="button" value="' + $.i18n._("js.answerYes") + '" class="yes"/><input type="button" value="' + $.i18n._("js.answerNo") + '" class="no"/></div>').replaceButtons();
					}
					content.find("input.yes").click(function() { window.location.href = link[1]; });
					content.find("input.no").click(function() {	p.boxy.hideAndUnload(); });
				}
			}		
			
			p.blendIn(null, true);
			p.boxy.animatedCenter();
			
		}
						
	};
	
	p.setOptions({success: ajaxSuccess});
	p.startRequest();;
};

/**
 * createAjaxRegistration()
 * Wrapper function for creating an Ajax registration
 *
 * @param options object An object, containing settings for AjaxPopup class
 * @return object a new AjaxRegistration object
 */
$.createAjaxRegistration = function(options) {
	return new AjaxRegistration(options);
}


/**
 * boxyLightbox()
 * Enables matches element, usually a link for opening in a boxy popup for magnifying an image
 *
 * @param options object An object
 */
$.fn.boxyLightbox = function(options) {
	var settings = $.extend({}, options);

	// add click handler to link
	this.click(function() {
		
		// create boxy object
		var b = new Boxy("<div class='boxy-image-content'><div class='boxy-loader'></div></div>", {title: "&#160;", closeText: $.i18n._("js.closeWindow"), modal: true, unloadOnHide: true, show: false});
		
		// create hidden image object
		var i = $('<img />').hide();
		
		// show boxy popup
		b.show();
		
		// attach loading handler to image object
		// it is important to attach this handler before setting src attribute
		// becuase otherwise, if image is already in browser cache it would load
		// instantly and load event would not fire!
		i.load(function() {
			b.getContent().find(".boxy-loader").fadeOut(250, function() {
				
				// dont't use animation in MSIE6 because it would cause flickering
				// callback function will show image after boxy resize completed
				if (!msie6) {
					// Boxy.tween() = animated resize 
					b.tween(i.width(), i.height(), function() { i.fadeIn(250); });
				} else {
					// Boxy.resize() = no animated resize
					b.resize(i.width(), i.height(), function() { i.fadeIn(250); });
				}
			})
		});
		
		// finally, set src attribute
		i.attr("src", $(this).attr("href"));
		
		// append image element to boxy content 
		b.getContent().append(i);
		return false;
	});
};

})(jQuery);

// initialize the page when the HTML/DOM is loaded
$(document).ready(function($) {

	// set dictionary for i18n
	// dictionary variable has to be declared before loading this file in global namespace
	if (typeof dictionary != "undefined") {
		$.i18n.setDictionary(dictionary);
	}
	
	// initialize all form behaviors on page
	$("body").initFormBehaviors();
	

	// initialize top navigation's smooth hover effect with "Get to know RebiSmart" and "I have a RebiSmart"
	$("#top-nav li.menu a.highlight").each(function() {
		$(this).removeClass("highlight").append('<span class="hover" />').each(function() {
			var s = $(this).find("span.hover").css("opacity", 0)
				.css("background-image", $(this).css("background-image"))
			s.hover(function () { s.stop().fadeTo(500, 1); }, function () {	s.stop().fadeTo(500, 0); });			
		});	
	} );
	
	// initalize hover effects for teaser navigation
	$('#teaser li.menu a.highlight').each(function() {
		if ($(this).parent().attr("class").match(/-active/)) {
			return;
		} else {
			$(this).removeClass('highlight').each(function() {
				var t = $(this);
				t.append('<span class="hover">' + t.html() + '</span>');
				var s = $('> span.hover', this).css("opacity", 0).css("background-image", t.css("background-image"));
				t.hover(function () { s.stop().fadeTo(500, 1); }, function () {	s.stop().fadeTo(500, 0); });
			})
		}
	});
	
	// init search field
	// when user focussed that field and it has it's default value, specified by a <label> element's text content
	// the field will be emptied. If user blurs field and it is empty, default value will be restored
	var defaultValue = $("#search-form #search-term-default-value").text();
	$("#searchTerm").val(defaultValue).focus(function() { if ($(this).val() == defaultValue) $(this).val(""); })
		.blur(function() { if ($(this).val() == "") $(this).val(defaultValue); });
	
	// init language selection dropdowns
	$("#languageToggleSelect, #globalLanguageToggleSelect, #availabilitySelect").initDropdown();
	
	// init country selection ajax registration
	$("#availabilitySelect ul li a").click(function() {
		$.createAjaxRegistration({formUrl: $(this).attr("href") });
		return false;
	});
			
	// init faq lists if there are any
	$(".faq-list dl").faqList();
	
	// init sitemap if there is one
	$(".sitemap-tree").treeview({ animated: true }); 
	
	// init boxy popup links#
	// call boxyLightbox function which attaches a click event to all lightbox-links
	$("a[rel='boxy-lightbox']").boxyLightbox();
		
	// init sitemap popup link
	$("#header-nav li a.sitemap-link").click(function() {
		// when clicking sitemap link, an ajax popup will be created
		// that loads the sitemap straight into the popup window.
		$.createAjaxPopup({
			url: $(this).attr("href").replace(/([a-zA-Z0-9-_]+)\.html/, "$1.xhtml"), // .html file ending will be replaced by .xhtml ending before starting request 
			success: function(data, textStatus, userContent) {
				// when request was successful, inject HTML code into popup and init the tree view of the sitemap.
				userContent.html(data).find(".sitemap-tree").treeview({ animated: true });	
			},
			contentClass: "boxy-sitemap-content"			
		});
		return false;
	});
});