(function() {
    
if (!("console" in window) || !("firebug" in console)) {
	var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
				 "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
	window.console = {};
	for (var i = 0; i < names.length; ++i)
		window.console[names[i]] = function() {};
};

String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g,"");
};
window.gifurl = function(options) {
    options = jQuery.extend({
        bg_color: "#FFFFFF",
        h: 25,
        w: 150,
        label: "OK",
        text_align: "center",
        text_valign: "middle",
        font_bold: 0,
        font_italic: 0,
        font_color: "#222222",
        font_size: 14,
        border_size: 0,
        border_color: "#000000",
        margin_left: 0,
        margin_right: 0,
        no_wrap: 0
    }, options);
    var url = "http://www.webinterpret.com/picture/gif_no_cache?";
    var args = "";
    jQuery.each(options, function(key, value){
        if (key == "label" || key == "bg_color" || key == "font_color" || key == "border_color") {
            value = encodeURIComponent(value);
        }
        args += "&" + key + "=" + value;
    });
    url += args.substring(1);
    return url;
}

/*
function trim(text) {
    return text.replace(/^\s+|\s+$/g,"");
};
*/

function getUniqueId() {
	return (new Date()).getTime();
}


function loadJS(url, addScriptId) {
	// TO AVOID DOUBLE REQUESTS AT IE
	var id = "script" + getUniqueId();
	if(addScriptId) {
		url += "&scriptId=" + id;
	}
	var script = document.createElement('script');
	script.setAttribute("type", "text/javascript");
	script.setAttribute("src", url);
	script.setAttribute("id", id);
	if (typeof script != "undefined")
		document.getElementsByTagName("head")[0].appendChild(script);
}

function loadCSS(url) {
	var style = document.createElement('link');
	style.setAttribute("type", "text/css");
	style.setAttribute("rel", "stylesheet");
	style.setAttribute("href", url);
	if (typeof style != "undefined")
		document.getElementsByTagName("head")[0].appendChild(style);
}

function setCookie(name, value, expires) {
document.cookie = name + "=" + 
escape(value) + "; path=/" + 
((expires == null) ? "" : "; expires=" + 
expires.toGMTString());
}

function getCookie (name) {
    var dc = document.cookie;
    var cname = name + "=";

    if (dc.length > 0) {
      begin = dc.indexOf(cname);
      if (begin != -1) {
        begin += cname.length;
        end = dc.indexOf(";", begin);
        if (end == -1) end = dc.length;
        return unescape(dc.substring(begin, end));
        }
      }
    return null;
}

function convertEntities(text)
{
    var matches = text.match( /\&\#(\d+);/g );

    if (!matches) {
        console.warn("No match"+text);
        return;
    } else {
        console.warn("No match! "+text);
    }

    for ( var i = 0; i < matches.length; i++ ) {
        text = text.replace( matches[i], convertEntity( matches[i] ) );
    }

    return text;

    function convertEntity( ent )
    {
        var num = parseInt(ent.replace(/\D/g, ''), 16);
        var esc = ((num < 16) ? '0' : '') + num.toString(16);
        return String.fromCharCode( esc );
    }
}


function hour2float(hour) {
    var splt = hour.split(":");
    var hour = parseFloat(splt[0]);
    var minute = parseFloat(splt[1]);
    return (hour + (minute/60.0));
}

function extract_end_hour(daterange) {
    var end_date = jQuery.trim(daterange.split("to")[1]);
    return jQuery.trim(end_date.split(" ")[1]);
}

function extract_day(daterange) {
    var end_date = jQuery.trim(daterange.split("to")[1]);
    return jQuery.trim(end_date.split(" ")[0]);
}

function detectServer() {
    var ctcServer = null;

	var html = document.getElementsByTagName("html").item(0);
	var head = html.getElementsByTagName("head").item(0);
	var body = html.getElementsByTagName("body").item(0);

	// detect ctcServer in head
	var scripts_list = [head.getElementsByTagName("script"), 
						body.getElementsByTagName("script")];
	for(var j=0; j < scripts_list.length; j++ ) {
		var scripts = scripts_list[j];
		for(var i=0; scripts.item(i); i++) {
			var script = scripts.item(i);
			if(script.getAttribute("type") == "text/javascript" &&
			   script.getAttribute("src") &&
			   script.getAttribute("src").indexOf("wi.js") >= 0)
			{
				ctcServer = script.getAttribute("src");
				ctcServer = ctcServer.substring(0, ctcServer.indexOf("wi.js") - 1);
			}
		}
	}
	return ctcServer;
}


var ecommerceTracker = function() {
var tracker = null;
var campaignId = null;
var transactions = [];

function track(t) {
	tracker._addTrans(t.orderID, campaignId, t.total, 
					  "", "", "", "", "");
	tracker._addItem(t.orderID, "", "fakeProduct", "", t.total, 1);
}

return {
	"setTracker": function(tr, cpgId) {
		console.debug("ecommerceTracker set");
		tracker = tr;
		campaignId = cpgId;
		if(transactions) {
			for(var j = 0; j < transactions.length; j++ ) {
				var t = transactions[j];
				track(t);
				console.debug("appended transaction added", t);
			}
			tracker._trackTrans();
			console.debug("appended transactions tracked");
			transactions = [];
		}
	},
    "trackTrans": function(orderID, total) {
		var t = {"orderID": orderID, "total": total};
		if(tracker) {
			track(t);
			tracker._trackTrans();
			console.debug("transactions tracked");
		} else {
			transactions.push(t);
		}
	}
};	
}();

function trackCampaign(trackerId, campaignId, lang) {
	var tracker = null;
	if(window._gat == null) {
		console.warn("still no ga, no ga tracking!");
	} else {
		tracker = _gat._getTracker(trackerId);
		tracker._setCustomVar(1, "CampaignId", campaignId, 3); 
		lang = lang ? lang : "original";
		tracker._setCustomVar(2, "Language", lang, 3);
		tracker._trackPageview();
		console.debug("page tracked, tracker:", trackerId, ", campaign:", campaignId, ", language:",  lang);
		ecommerceTracker.setTracker(tracker, campaignId);
	}
};


function loadDeps(loadTranslationApi, loadJQuery, loaded) {
	var ourjQuery = false;
	var ourGA = false;
    var mltbServer = detectServer() + '/';
    
	if(window.jQuery == null) {
		console.debug("no jquery, importing!");
		var jQueryUrl = "http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js";
		document.write(unescape("%3Cscript src='" + jQueryUrl + "' type='text/javascript'%3E%3C/script%3E"));
		ourjQuery = true;
	}

	if(loadTranslationApi && (window.google == null || window.google.load == null)) {
		document.write(unescape("%3Cscript src='http://www.google.com/jsapi' type='text/javascript'%3E%3C/script%3E"));
	}

	if(window._gat == null) {
		console.debug("no ga, importing!");
		var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
		document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
		ourGA = true;
	}
    
    // load alien CSS
    loadCSS(mltbServer + "mltb/toolbar_style.css");

	var jQueryReady = false;
	var GAReady = false;
	var googleTranslationApiReady = false;
	var googleJSApiReady = false;
	var period = 100;
	var iterations = 0;
	
	window._CTCheckScripts = function() {
		if(loadJQuery && window.jQuery != null && !jQueryReady) {
			console.debug("jQuery ready");
			jQueryReady = true;
			if(ourjQuery) {
				jQuery.noConflict();				
			}
		}

		if(window._gat != null && !GAReady) {
			console.debug("GA ready");
			GAReady = true;
		}

    	if(loadTranslationApi && 
		   window.google != null && 
		   window.google.load != null &&
		   !googleJSApiReady) 
		{
			googleJSApiReady = true; 
		    google.load("language", "1", {"callback": function() {
				console.debug("TranslationApi ready");
			    googleTranslationApiReady = true;
			}});
		}

		if((jQueryReady || !loadJQuery) && 
		   (googleTranslationApiReady || !loadTranslationApi)) 
		{
			if(GAReady || iterations*period > 2000) {
				if(!GAReady) {
					console.debug("Can't fetch ga. Proceeding without it.");
				}
				console.debug("All Deps ready");
				loaded(); 				
				return;
			}
		}
		iterations++;
		window.setTimeout('_CTCheckScripts()', period);
	};
	_CTCheckScripts();
};

window._initCTC = function(params) {

	var emailReg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
	var phoneReg = /^[+0-9 ]{1,20}$/;

	var campaignId = params.campaign;
	var formLang = params.formLang ? params.formLang : null;
	var logo = params.logo ? params.logo : null;
	var ask4ClientLang = params.ask4ClientLang ? params.ask4ClientLang : false;

	var offererLang = params.offererLang ? params.offererLang : null;
	var offererEmail = params.offererEmail ? params.offererEmail : null;
	var offererTimezone = params.offererTimezone ? params.offererTimezone : "";
	var offererServiceName = params.offererServiceName ? params.offererServiceName : null;
    
	var clientTimezone = params.clientTimezone ? params.clientTimezone : "";
	var clientServiceName = params.clientServiceName ? params.clientServiceName : null;

	var ctcServer = detectServer();

	if(ctcServer == null) {
		console.warn("No ctcServer defined.");		
	} else if(ctcServer == "") {
		console.debug("Relative ctcServer location found.");		
	} else {
		console.debug("ctcServer: ", ctcServer);
	}


	var pageLang = params.pageLang;
	
	var editSecret = null;
    var dontTranslate = false;

	var hash = document.location.hash.substring(1);

	var extraParams = hash.split(",");
	for(var i = 0; i < extraParams.length; i++) {
		var p = extraParams[i].split("=");
		if(p[0] == 'translate_to') {
			formLang = p[1];
		} else if(p[0] == 'edit') {
            editSecret = p[1];
		}
          else if(p[0] == 'no_translation') {
            setCookie('translate_to','');
            return;
        }
	}


	if(hash.indexOf("translate_to=") == 0) {
		if(!pageLang) {
			console.warn("page language not set!");
			return;
		}
        setCookie('translate_to',formLang);
	} else {
        formLang = getCookie('translate_to');
		if(!formLang) {
            if (pageLang) {
                formLang = pageLang;
                console.warn("form language not set!");			
                dontTranslate = true;
            }
		}
	}
    
    
	var invalidStyle = {'background-color' : '#FFAFAF'};
	var validStyle = {'background-color' : '#FFF'};

    function addFormHandlers(elems, template) {
		var currentDay = template.find("input[name='currentDay']").val();
		var currentHour = parseInt(template.find("input[name='currentHour']").val());
		var officeHourStart = template.find("input[name='officeHourStart']").val();
		var officeHourEnd = template.find("input[name='officeHourEnd']").val();

        window._formSubmitted = function (formId, scriptId, result, reqId) {
            console.debug('Data sent and answer:', result, 'received for form: ', 
                          formId, ' via script:', scriptId);

			if(scriptId) {
				jQuery("#" + scriptId).remove();
			}            
            //jQuery(".ctcWidget").hide();
            // show information about sending status
            
            var widget = jQuery("#" + formId);
            if(result == 'payment_summary') {
                jQuery("#_ctcFakeForm")
                .attr("action", ctcServer + "/ctc/summary")
                .empty()
                .append("<input name='id' value='" + reqId + "'>")
                .submit();
            } else {
                widget.find(".ctcLoading").hide();
                widget.removeAttr("id");
                if(result == 'saved') {
                    widget.find(".ctcOK").show();
                    widget.find("#submit-result-for-selenium").val('1');
                } else if(result == 'etr_saved') {
                    widget.find(".etrOK").show();
                    widget.find("#submit-result-for-selenium").val('1');
                } else if(result == 'not_found') {
                    widget.find(".ctcErrorNotFound").show();
                } else if(result == 'not_enabled') {
                    widget.find(".ctcErrorNotEnabled").show();
                } else if(result == 'exception') {
                    widget.find(".ctcErrorException").show();
                } else {
                    widget.find(".ctcErrorException").show();
                }
            }
        };

		elems.each(function(e) {
			var widget = template.clone(true);

			jQuery(this).append(widget);

			var day = widget.find("select[name='day']");

			var email = widget.find("input[name='email']");
            var email2 = widget.find("input[name='emailEmail']");
			var phone = widget.find("input[name='phone']");

			day.change();

			widget.show();

            function showCtcCallTab() {
                widget.find("#ctcEmailForm").hide();
                widget.find("#ctcCallForm").show();
                widget.find("#ctcCall").css({"background-color":"#ddd","font-weight":"bold"});
                widget.find("#ctcEmail").css({"background-color":"#fff","font-weight":"normal"});
            };
            
			function showEtrTab() {
                widget.find("#ctcCallForm").hide();
                widget.find("#ctcEmailForm").show();
                widget.find("#ctcEmail").css({"background-color":"#ddd","font-weight":"bold"});
                widget.find("#ctcCall").css({"background-color":"#fff","font-weight":"normal"});
            };

            widget.find("#ctcCall").click(showCtcCallTab);
            widget.find("#ctcEmail").click(showEtrTab);

			widget.find(".ctcReset").click(function() {
				// RESETING VARS
				widget.find(".ctcField:not(.ctcDontReset)").each(function() {
					jQuery(this).val('');
				});
				widget.find(".ctcFieldEmail:not(.ctcDontReset)").each(function() {
					jQuery(this).val('');
				});

                showCtcCallTab();

				day.change();

				widget.find(".ctcMessage").hide();
                widget.find("#submit-result-for-selenium").val('0');
				widget.find(".ctcBody").show();

				if(widget.find(".ctcClose").html() != null){
					widget.find(".ctcClose").show();
					jQuery("#wiCtc", document).hide('slow');
				}
                
                if(widget.find(".ctcCloseFloatingBar").html() != null) {
                    widget.find(".ctcMessage").hide();
                    jQuery(".ctc-form-floatingbar").hide();
                }
			});
            
            widget.find(".ctcSubmitEmail").click(function() {
                var formValid = true;
                
                var widgetHeight = widget.find(".ctcBody").height();
    			widget.find(".ctcMessage").css('height', widgetHeight);

				widget.find(".ctcFieldEmail").css(validStyle);
                
                widget.find(".ctcFieldEmail").each(function() {
                    var field = jQuery(this);
                    if(jQuery.trim(field.val()) == '' && field.attr('optional') == undefined)    
					{
						console.debug("invalid:", field.attr("name"), "=", field.val());
						field.css(invalidStyle);
						formValid = false; 
					}
                });
                
                if(email2.size() && !emailReg.test(email2.val())) {
					console.debug("invalid: email");
					email2.css(invalidStyle);
					formValid = false;
				}
                
                if(formValid) {
					widget.find(".ctcLoading").show();
					widget.find(".ctcBody").hide();
					widget.find(".ctcClose").hide();
                    
                    formId = "submitted" + getUniqueId();
                    widget.attr("id", formId);
                    submitUrl = "";

                    widget.find(".ctcFieldEmail").each(function() {
                        var field = jQuery(this);
                        if(field.val() != '') {
                            submitUrl += "&" + field.attr("name") + "=" + field.val();
                        }
                    });

                    submitUrl += "&formId=" + formId;
                    submitUrl = ctcServer + "/ctc/submit_etr?" + submitUrl.substring(1);

                    console.debug('Sending from e-mail form: ' + submitUrl);
                    loadJS(submitUrl);
                }
            });
            
			widget.find(".ctcSubmit").click(function() {
				// CALL ME FORM VALIDATION
				var formValid = true;
                
    			var widgetHeight = widget.find(".ctcBody").height();
    			widget.find(".ctcMessage").css('height', widgetHeight);

				widget.find(".ctcField").css(validStyle);

				widget.find(".ctcField").each(function() {
					var field = jQuery(this);
					//console.debug(field.attr("name"), field.val(), field.val() == '', !field.attr('mandatory') == 'false');
				    if(field.val() == '' && field.attr('optional') == undefined) 					    
					{
						console.debug("invalid:", field.attr("name"), "=", field.val());
						field.css(invalidStyle);
						formValid = false; 
					}
				});

                if(!phoneReg.test(phone.val())) {
					console.debug("invalid: phone number: " + phone.val());
					phone.css(invalidStyle);
					formValid = false;
                }

				if(email.size() && !emailReg.test(email.val())) {
					console.debug("invalid: email");
					email.css(invalidStyle);
					formValid = false;
				}

				if(formValid) {
					widget.find(".ctcLoading").show();
					widget.find(".ctcBody").hide();
					widget.find(".ctcClose").hide();

					formId = "submitted" + getUniqueId();

					widget.attr("id", formId);

					submitUrl = "";

					widget.find(".ctcField").each(function() {
					    var field = jQuery(this);
						if(field.val() != '') {
							submitUrl += "&" + field.attr("name") + "=" + field.val();
						}
				    });

					submitUrl += "&formId=" + formId;

					submitUrl = ctcServer + "/ctc/submit?" + submitUrl.substring(1);

					console.debug('Sending: ' + submitUrl);

                    loadJS(submitUrl);
				} else {
					console.debug(widget);
				}
			});//widget.find(".ctcSubmit")
		}); //elems.each(
	} //addFormHandlers

	function initCTCForm(found, enabled,  
						 formHtml, formStyle, formStyleGlobal,
						 glossary, fix) 
	{
        
		function initForm(template) {
			console.debug("init form called:", campaignId);

			var formEventSent = false;

			var are_styles = jQuery('.ctcWidget').css('backgroundColor');
			if(are_styles == 'transparent' || are_styles == 'rgba(0, 0, 0, 0)'){
				jQuery("head").append('<style type="text/css">' + formStyle + '</style>');
			}
			jQuery("head").append('<style type="text/css">' + formStyleGlobal + '</style>');

			// FORMS OPENED BY CTC BUTTONS	
			jQuery("body").append('<div id="wiCtc" style="display: none; position: absolute;"></div>');
			addFormHandlers(jQuery("#wiCtc"), template);

			jQuery(".ctc", document).each(function() {
			    jQuery(this).click(function() {
					// POSITION OF FLOATING WIDGET
					var scrollTop;
					if(self.pageYOffset){
						scrollTop = self.pageYOffset;
					} else if(document.documentElement && document.documentElement.scrollTop){ // Explorer 6 Strict
						scrollTop = document.documentElement.scrollTop;
					} else if(document.body){ // all other Explorers
						scrollTop = document.body.scrollTop;
					}
					var elementPosition = jQuery(this).offset();
					var widgetHeight = jQuery("#wiCtc").height();
					var elementHeight = jQuery(this).height();
					var windowHeight = jQuery(window).height();
					var spaceAbove = elementPosition.top - scrollTop;
					var spaceBelow = windowHeight - spaceAbove - elementHeight;

					if(spaceBelow >= widgetHeight){
						widgetY = elementPosition.top + elementHeight;
					} else if(spaceAbove >= widgetHeight){
						widgetY = elementPosition.top - widgetHeight;
					} else {
						if(widgetHeight <= windowHeight) {
							widgetY = scrollTop + (windowHeight - widgetHeight) / 2;
						} else {
							widgetY = scrollTop;
						}
					}

					// SHOWING WIDGET
					jQuery("#wiCtc").show();
					jQuery("#wiCtc").css('top', widgetY + 'px'); 
					jQuery("#wiCtc").css('left', elementPosition.left + 'px');

					var close = jQuery("#wiCtc").find(".ctcClose");

					jQuery(close).click(function() {
					    jQuery("#wiCtc").hide();
					});
			    });
			});
            
			//Let's remove close button from template, 
			//from now it is going to be used just for inline forms
			jQuery(".ctcClose", template).remove();
			addFormHandlers(jQuery(".ctc-form"), template);
            
            //Floating Bar Form
            jQuery(".ctc-form-floatingbar .ctcBody")
				.prepend("<div class='ctcCloseFloatingBar' style='right:0px;'>x</div>");
            jQuery(".ctcFloatingBarButton").click(function() {
                jQuery(".ctc-form-floatingbar").show();
            });
            jQuery(".ctcCloseFloatingBar").click(function() {
                jQuery(".ctc-form-floatingbar").hide();
            });
		} //initForm;

		console.debug("_initCTCForm called: ", campaignId, found, enabled);
		var formTemplate = document.createElement("div");
		formTemplate.style.display = "none";
		document.body.appendChild(formTemplate);
		jQuery(formTemplate).html(formHtml);

		initForm(jQuery(formTemplate));
		jQuery("body").append("<form id='_ctcFakeForm' method='get' style='display: none'> </form>");		
	}; //initCTCForm

	var formUrl = ctcServer +
		      "/ctc/form?campaign=" + campaignId + 
		      "&ask4ClientLang=" + ask4ClientLang + 
		      "&formLang=" + formLang +
		      "&clientTimezone=" + clientTimezone +
		      "&offererTimezone=" + offererTimezone +
		      "&offererLang=" + offererLang + 
		      "&offererEmail=" + encodeURIComponent(offererEmail);

	if(clientServiceName) {
		formUrl += "&clientServiceName=" + clientServiceName;
	}

	if(offererServiceName) {
		formUrl += "&offererServiceName=" + offererServiceName;
	}		

	if(logo) {
		formUrl += "&logo=" + logo;
	}		

    //TODO: fix controler
	if(true) {
		formUrl += "&mltb=" + pageLang + "," + formLang;
	}		

	console.debug("including form: " + formUrl);

	var continuation = false;
	window._initCTCForm = function (found, enabled, gaTrackerId, 
									formHtml, formStyle, formStyleGlobal,
									exceptions, overrides, fix) 
	{
		function cont() {            
            var languageTo = getCookie('translate_to');
            
            if (languageTo && !editSecret) {                
                jQuery(document.body).prepend(
                    "<div class='ctcFloatingBar'>" +
                        "<!--<div id='ctc_message'></div>-->" +
                        "<div id='ctc_show_original'></div>" +
                        "<div class='ctcButtonSpace'>" +
                        "<button class='ctcFloatingBarButton'>Any questions ?</button></div>" +
                    "</div>"+
                    "<div class='ctc-form-floatingbar' style='display:none;'><div class='ctc-form'></div></div>"
                    );
                jQuery(document.body).append("<div class='filler'></div>");
            }

			if(pageLang && !dontTranslate) {
				trackCampaign(gaTrackerId, campaignId, languageTo);
				translate(window.document, pageLang, formLang, exceptions, overrides, fix, campaignId, editSecret,
					function(all, translated) { 
						//jQuery("#ctc_message").html("Translation: " + parseInt(100 * translated / all) +  "%");
						if(all == translated) {
							//jQuery("#ctc_message").html(translation('translated_info'));
                            var current_url = document.location;
                            if (current_url.hash.indexOf("#translate_to=")==0)
                            {
                                current_url = new String(current_url);
                                current_url = current_url.substring(0, current_url.indexOf("#translate_to"));
                            }
                            
                            /*jQuery("#ctc_show_original").html("<a href='" + current_url
                                                         + "'><img class='dontEdit' src='http://www.webinterpret.com/images/flags/" 
                                                         + pageLang +".gif'></a>");
                            jQuery("#ctc_show_original").click(function() {
                                setCookie('translate_to','');
                            });*/
							initCTCForm(found, enabled, 
										formHtml, formStyle, formStyleGlobal,
										overrides, fix);
						}
					});
			} else {
				trackCampaign(gaTrackerId, campaignId);
				initCTCForm(found, enabled,  
							formHtml, formStyle, formStyleGlobal,
							overrides, fix);
			}
		} //cont;

		if(continuation) {
			cont();
		} else {
			continuation = cont;
		};
	};

	loadDeps(true, true, function() {
		if(continuation) {
			continuation();
		} else {	
			continuation = true;
		}
	});

	loadJS(formUrl, false);

	return ecommerceTracker;
}; //window._initCTC


//TODO: fix that
window._initCTCRequest = function(params) {
	var ctcServer = detectServer();

	var campaignId = params.campaign;

	window._sendCTCRequest = function(params) {
		var ctcString = detectServer() + '/ctc/submit';
        ctcString += '?countryCodeSelector=';
        ctcString += '&countryCode=';
        ctcString += '&phone=' + params.phone;
        ctcString += '&campaign=' + campaignId;
        ctcString += '&clientLang=' + params.language;
        ctcString += '&day=' + params.date;
        ctcString += '&hour=' + params.hour;
        ctcString += '&clientTimezone=Europe/Paris'; // GET

		if(params.callback) {
			window._formSubmitted = function (formId, scriptId, result) {
				console.debug('Data sent and answer:', result, 'received via script:', scriptId);
				params.callback();
			};
		} else {
			window._formSubmitted = function (formId, scriptId, result) {};
		}
		loadJS(ctcString);
		return true;
	};

	window._initCTCTracker = function(found, enabled, gaTrackerId) {
		console.debug("tracker received: " + gaTrackerId);
		loadDeps(false, false, function() {
			trackCampaign(gaTrackerId, campaignId);
		});
	};

	trackerUrl = ctcServer + "/ctc/tracker?campaign=" + campaignId;

	console.debug("asking for tracker: " + trackerUrl);
	document.write(unescape("%3Cscript defer src='" + trackerUrl + "' type='text/javascript'%3E%3C/script%3E"));
}; //window._initCTCRequest

function translate(doc, srcLang, dstLang, exceptions, overrides, fix, 
				   campaignId, editSecret, callback) {

	var regexNBSP = new RegExp(String.fromCharCode(160), "g");
	var regexSP = new RegExp(String.fromCharCode(32), "g");

	function fixWhiteSpaces(orig, translated) {
	    // add &nbsp; if needed to keep right design of pages
	    var testText = orig.trim();
        if(regexNBSP.test(testText) && !regexSP.test(testText)) {
			translated = translated.replace(/ /g, '\u00A0');
		}
        // add empty space to as first or last character to keep text nodes look right
        if(jQuery.browser.msie && jQuery.browser.version.substr(0,1) < 8) {
			translated = " " + translated + " ";
        } else {
    		if(orig[0] == " " || orig[0] == "\n")
    			translated = " " + translated;
    		if(orig[orig.length - 1] == " " || orig[orig.length - 1] == "\n")
    			translated += " ";
        }
		//console.warn(orig, "===>", translated);
		return translated;
	}

	function groupTexts(elem, overrides, groupLength, f) {
		/* group elements into groups no longer that groupLenght long,
		 * if element is longer break it into pieces. 
		 */

		var texts = [];
		var totalLength = 0;

		function pushText(text, setter) {
            if(totalLength + text.length > groupLength) {
				f(texts);
				texts = [];
				totalLength = 0;
			} 
			texts.push({"text": text, "set": setter});								   
			totalLength += text.length;				
		}

		function flushTexts() {
        	if(texts) {
				f(texts);
			}
		}

		function breakAndPush(text, setter) {
			if(text.replace(/[ \n\r\t]/g, "")) { //not empty
				if(text.length < groupLength) { //not too long
					//console.debug("pushing text: ", text.length, " under: ", groupLength, text);
					pushText(text, function(translation) {
						setter(fixWhiteSpaces(text, translation));
					});
				} else { //text too long, lets split it
					var acc = ""; //accumulator for translated fragments
					var tail = text;
					while(true) {
						var fragment = tail.substr(0, groupLength);
						if(fragment.length < tail.length) {
							for(var splitChar in {". ": 1, ", ": 1, "\n": 1, " ": 1}) {
								var splitIndex = fragment.lastIndexOf(splitChar);
								if(splitIndex >= 0) {
									//console.debug("long text broken at: '", splitChar, "'", fragment);
									fragment = fragment.substr(0, splitIndex + splitChar.length);
									break;
								}
							}
						}
						tail = tail.substr(fragment.length);
						if(tail) {
							//console.debug("pushing text fragment:", fragment.length, fragment, "tail: ", tail);
							pushText(fragment, function(translation) {
								acc += fixWhiteSpaces(fragment, translation);
							});
						} else {
							//console.debug("pushing last text fragment:", fragment.length, fragment);
							pushText(fragment, function(translation) {
								setter(acc + fixWhiteSpaces(fragment, translation));
								acc = null; //not sure if necessary
							});								
							break;
						}
					}
				}
			}
		}

		function useGlossaryOrPush(text, push, setter) {
			var trimmed = jQuery.trim(text);
            //console.warn(trimmed);
            var override = overrides[trimmed];
            if(override) {
				setter(fixWhiteSpaces(text, override));
			} else {
				override = exceptions[trimmed];
				if(override) {
					setter(override);					
				} else {
					var orig = text;
					jQuery.each(exceptions, function(term, override) {
						//TODO: optimization oportunity here
						override = ["<span class='notranslate'>", 
									override === undefined ? term : override, 
									"</span>"].join("");
						text = text.replace(new RegExp(term, "g"), override);
					});
					if(orig != text) {
						console.debug("exception applied:", orig, "->", text);
						push(text, function(text) {
							setter(text.replace("<span class='notranslate'>", "")
								   .replace("</span>", ""));
						});
					} else {
						push(text, setter);
					}
				}		
			}
		};

		function markAsEditable(element, text, push, setter){
			if((top.partnerWindow || editSecret) && text.trim()) {
				var texts = element.data('texts');
				if(!texts) {
					texts = new Array();
				}
				var placeholder = [text.trim(), undefined];
				texts.push(placeholder);
				element.data('texts', texts);
				element.addClass('editModeElement');				
				useGlossaryOrPush(text, push, function(translation) {                    
					placeholder[1] = translation.trim();                        
					setter(translation);
				});
			} else {
				useGlossaryOrPush(text, push, setter);
			}
		};

		function handleElement(key, value) {
			if(value.nodeType === 3) { //i.e. textNode
				if (jQuery(value).parent().get(0).nodeName.toLowerCase() != 'textarea') {
					markAsEditable(jQuery(value).parent(), value.nodeValue, breakAndPush, function(translation) {
                        value.data = translation;
    				});
				}
			} else if(value.nodeType === 1) {
				var nodeName = value.nodeName.toLowerCase();
                
				value = jQuery(value);
				if(nodeName == "input" &&
				   value.attr("type") && (value.attr("type") == 'submit' ||
					                      value.attr("type") == 'button' ||
					                      value.attr("type") == 'reset')) 
				{
					markAsEditable(value, 
								   value.attr("value"), pushText, 
								   function(translation) {
                					   value.attr("value", translation);
								   });
				} else if(nodeName != "form" && value.attr("title")) {
					markAsEditable(value,
								   value.attr("title"), breakAndPush, 
								   function(translation) {
            						   value.attr("title", translation);
								   });
				} else if(nodeName != "form" && value.attr("alt")) {
					markAsEditable(value,
								   value.attr("alt"), pushText, 
								   function(translation) {
            						   value.attr("alt", translation);
								   });
				}
			}
		}
        elem.each(handleElement);			  
		flushTexts();
    }; //groupTexts

    function buildEditor(texts) {
        var editor = '<div id="editor">';
        editor += '<div class="i">'
				  + '<b class="close" onclick="jQuery(\'#editor\').remove(); return false;">&#10006;</b>'
				  + '<div class="title">Overrides Editor</div>';
        for(var i = 0; i < texts.length; i++) {
            if(texts[i][0] != '') {
                editor += '<div class="field">';
                if(!i) { 
					editor += '<span style="border-right: 0;">Original</span>';
			    }
                editor += '<div class="i" style="border-right: 0;">';
                editor += '<textarea class="original" name="original_' 
					+ i 
					+ '" cols="1" rows="1" readonly="readonly">' 
					+ texts[i][0] + '</textarea>';
                editor += '</div>';
                editor += '</div>';
                editor += '<div class="field">';
                if(!i) {
					editor += '<span>Translation</span>';
				}
                editor += '<div class="i">';
                editor += '<textarea class="translation" name="translation_' 
					+ i + '" cols="1" rows="1">' 
					+ texts[i][1] + '</textarea>';
                editor += '</div>';
                editor += '</div>';
				editor += '<div class="clear"></div>';
            }
        }
        editor += '<div class="buttons">'
			+ '<button id="saveButton" style="background: #2FA2FF;">Save</button>';
        editor += '<button id="cancelButton" onclick="jQuery(\'#editor\').remove(); return false;" style="background: #FF3300;">Cancel</button>';
        editor += '<span class="preloader"><img src="' 
			+ detectServer() 
			+ '/images/ajax_loading.gif" style="vertical-align: middle;" /> Saving...</span>';
        editor += '</div></div></div>';
        return editor;
    }

	function editOverrides() {
		jQuery(doc).find('a').attr('href', '#');
        jQuery(doc).find('form').attr('action', '#');
        jQuery(doc).find('*').attr('onclick', '');
        jQuery(doc).find('a').removeAttr('target');
        jQuery(document).find('.editModeElement').addClass('editModeElementHighlighted');
        jQuery(doc).find('.editModeElement').click(function(event) {
            event.stopPropagation();
            var texts = jQuery(this).data('texts');
            if(texts && texts[0] && texts[0][0] != "") {
				var fieldHeight = parseInt((jQuery(window).height() - 180) / texts.length) - texts.length;
				var editor = buildEditor(texts);

	            jQuery('#editor').remove();
    	        jQuery('body').append(editor);
    	        jQuery('#editor textarea').css('height', fieldHeight + 'px');
    	        jQuery('#editor').show()
    	                         .css('top', parseInt((jQuery(window).height() - jQuery('#editor').height()) / 2) + 'px')
    	                         .css('left', parseInt((jQuery(window).width() - jQuery('#editor').width()) / 2) + 'px');
                jQuery('#editor #saveButton').click(function(){
                    jQuery('#editor #cancelButton').hide();
                    jQuery('#editor #saveButton').hide();
                    jQuery('#editor .preloader').show();

                    var query = detectServer() + '/';

                    query += 'ctc/mltb_glossary_input';
                    query += '?secret=' + editSecret;
                    query += '&campaignId=' + campaignId;
                    query += '&languageFrom=' + srcLang;
                    query += '&languageTo=' + dstLang;

                    jQuery('#editor .original').each(function(){
                        query += '&original=' + encodeURIComponent(jQuery(this).val());
                    });
                    jQuery('#editor .translation').each(function(){
                        query += '&translation=' + encodeURIComponent(jQuery(this).val());
                    });
			        jQuery.getScript(query);
                });
            }
		});
	}

    function disableLink(e) {
        e.preventDefault();
        return false;
    }

    function editOverrides3() {
        
        var editorWindow;
        window.focus();
        
        var isHighlighted = true;
        jQuery(document).find('.editModeElement').addClass('editModeElementHighlighted')
                .bind('click', disableLink);
        
        jQuery(document).keyup(function(e) {
            //console.debug(e.which);
            if (e.which == 17 && !isHighlighted) {
                jQuery(document).find('.editModeElement').addClass('editModeElementHighlighted')
                .bind('click', disableLink);
                isHighlighted = true;
            }
        });
        
        jQuery(document).keydown(function(e) {
            if (isHighlighted) {
                jQuery(document).find('.editModeElement').removeClass('editModeElementHighlighted')
                .unbind('click', disableLink);
                isHighlighted = false;
            }
        });

        jQuery(doc).find('form').attr('action', '#');
        
        jQuery(doc).find('.editModeElement').click(function(event) {
            if (!isHighlighted) { 
                return; 
            }
            event.stopPropagation();

            texts = jQuery(this).data('texts');
            var original = "";
            var translation = "";
            
            //var query = 'http://' + editSecret + '/ctcadmin/edit/'+campaignId+'/'+dstLang;
            
            var query = detectServer() + '/ctcadmin/edit/'+campaignId+'/'+dstLang;
            //query += '#campaignId=' + campaignId;
            query += '#languageFrom=' + srcLang;
            query += '&languageTo=' + dstLang;
            							   

            for (var i=0; i<texts.length; ++i) {
                original = texts[i][0];
                translation = texts[i][1];
                query += "&original=" + encodeURIComponent(original);
                query += "&translation=" + encodeURIComponent(translation);
            }
            query += '&partner=' + window.location.href;
            top.location = query;
		});
    }

	function editOverrides2() {
        var editorWindow;
		jQuery(doc).find('a').attr('href', '#');
        jQuery(doc).find('form').attr('action', '#');
        jQuery(doc).find('*').attr('onclick', '');
        jQuery(doc).find('a').removeAttr('target');
        jQuery(doc).find('.editModeElement').click(function(event) {
            event.stopPropagation();
			//console.debug(top.widgetEditor);
            texts = jQuery(this).data('texts');
            var original = "";
            var translation = "";
            
            var query = detectServer() + '/ctc/neweditor';
            query += '#campaignId=' + campaignId;
            query += '&languageFrom=' + srcLang;
            query += '&languageTo=' + dstLang;
            query += '&referer=' + window.location.href;

			console.info(texts);							   
            
            for (var i=0; i<texts.length; ++i) {
                original = texts[i][0];
                translation = texts[i][1];
                query += "&original=" + encodeURIComponent(original);
                query += "&translation=" + encodeURIComponent(translation);
            }
            
            if (editorWindow && editorWindow.open && !editorWindow.closed) {
                editorWindow.location = query;
            } else {
                editorWindow = window.open(query, "widgetEditor", "menubar=no,width=430,height=360,toolbar=no");
            }
            editorWindow.focus();
		});
	}
    
    window.editError = function(info){
        jQuery('#editor .preloader').html('<b style="color: red;">' + info + '</b>');
    };

    window.editOK = function(info){
        jQuery('#editor .preloader').html('<b style="color: green;">' + info + '</b>');
        setTimeout("jQuery('#editor').remove()", 500);
        if (window.location.hash == '') {
            location.href = window.location.href + 'translate_to=' + dstLang + ',edit=' + editSecret;
        }
        location.reload();
    };
    
	console.debug('Translating...');

	var context = 0;
	var texts = [];
	var totalLength = 0;
	var allTexts = {};

	var translated = 0;
	var all = 0;
	var isAlreadyDone = false;

	// timing
	var start = new Date();

	function fixTranslation(t) {        
		return t.replace(/&#39;/g, "'")
			.replace(/&quot;/g, '"')
			.replace(/&lt;/g, "<")
			.replace(/&gt;/g, ">")
			.replace(/&amp;/g, "&");
	}

	window._translatedCallback = function(context, result) {
        
		jQuery(result).each(function(index, value) {
			var translatedText = value.responseData ? 
									value.responseData.translatedText : 
									value.translatedText;
			if(translatedText){
				allTexts[context][index].set(fixTranslation(translatedText));
			}
			delete allTexts[context][index];					
		});
		translated++;
		if(all) {
			callback(all, translated);
		}
		if(all && translated == all && !isAlreadyDone) {
			isAlreadyDone = true;
			try {
				fix(doc, dstLang, ecommerceTracker);
			} catch (x) {
				console.error("Exception in fix function: " + x);
			}
			console.debug('Translated in: ' + 
						  (new Date().getTime() - start.getTime()) + ' ms');
            if(top.partnerWindow) {
				editOverrides3();
			}
            else if (editSecret && editSecret=='snow') {
                editOverrides();
            }
		}
	};

	groupTexts(jQuery(doc).find('html').find(":not(script,style,.ctcWidget)").contents(), 
			   overrides, 600, function(texts) {
    
		var url = "http://ajax.googleapis.com/ajax/services/language/translate?v=1.0";
        
		url += "&langpair=" + srcLang + "|" + dstLang ;									
		jQuery(texts).each(function() {
			url += "&q=" + encodeURIComponent(this.text);
		});
		url += "&context=" + context; 
		url += "&callback=_translatedCallback";
		allTexts[context] = texts;
		jQuery.getScript(url);
		context++;									
	});
	all = context;
};
})();
