console.log("starting to load application.js");

dojo.require("dojo.fx");
dojo.require("dijit.Tooltip");
dojo.require("dijit.TitlePane");
dojo.require("dojox.widget.Toaster");
dojo.require("dijit.Dialog");
dojo.require("dijit.Menu");
dojo.require("dijit.form.TextBox");
dojo.require("dijit.form.Textarea");
dojo.require("dijit.form.DateTextBox");
dojo.require("dijit.form.NumberTextBox");
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.form.CheckBox");
dojo.require("dijit.form.FilteringSelect");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.Form");
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.layout.StackContainer");
dojo.require("dojo.parser");
var webRoot = "http://www.blogscope.net/";

function $() {
  var elements = new Array();

  for (var i = 0; i < arguments.length; i++) {
    var element = arguments[i];
    if (typeof element == 'string')
      element = document.getElementById(element);

    if (arguments.length == 1)
      return element;

    elements.push(element);
  }

  return elements;
}

function highlight(/* DomeNode */ node) {	
	var highlightAnim = dojo.animateProperty({
   	  	node: node,
 		duration: 2000,
		properties: {
    	backgroundColor: { start:"#ffff99", end: "#ffffff" }
    	}
	});
	highlightAnim.play();
}


function searchFocus(e) {
	if (e.value == 'Enter Search Term Here') {
		e.value = '';
		e.style.color = 'black';
		searchIsDisabled = false;
	}
}

function searchBlur(e) {
	if (e.value == '') {
		e.value = 'Enter Search Term Here';
		e.style.color = 'gray';
		searchIsDisabled = true;
	}
}

function removeAndAnimate(/*DomNode*/ domnode) {
	dojo.fx.wipeOut({node: domnode,duration: 1000}).play();
}

function showAndAnimate(/*DomNode*/ domnode) {
	dojo.fx.wipeIn({node: domnode, duration: 1000}).play();
}

function updateRestrictDates() {
	var rdatesCbox = document.getElementById("restrictdates");
	var datecontrolsActive = rdatesCbox.checked;
	var dateControlSpan = document.getElementById("datecontrols");
	var datestartDropdown = document.getElementById("datestart");
	var monthstartDropdown = document.getElementById("monthstart");
	var yearstartDropdown = document.getElementById("yearstart");
	var dateendDropdown = document.getElementById("dateend");
	var monthendDropdown = document.getElementById("monthend");
	var yearendDropdown = document.getElementById("yearend");
	if (datecontrolsActive == true) {
		dateControlSpan.style.color = '#000000';
		datestartDropdown.disabled = false;
		monthstartDropdown.disabled = false;
		yearstartDropdown.disabled = false;
		dateendDropdown.disabled = false;
		monthendDropdown.disabled = false;
		yearendDropdown.disabled = false;
	} else {
		dateControlSpan.style.color = '#bbbbbb';
		datestartDropdown.disabled = true;
		monthstartDropdown.disabled = true;
		yearstartDropdown.disabled = true;
		dateendDropdown.disabled = true;
		monthendDropdown.disabled = true;
		yearendDropdown.disabled = true;
	}
}

function setDisplayToBlock(/*String*/ id) {
	dojo.byId(id).style.display="block";
}

function toggleVisibility(/*String*/ id) {
	var curr = $(id).style.display;
	if (curr == "none") {
		dojo.byId(id).style.display = "block";
	} else {
		dojo.byId(id).style.display = "none";
	}
}

function toggleExpandCollapse(blockId, imageId) {
    var blockElement = $(blockId);
    var imageElement = $(imageId);
	var curr = blockElement.style.display;
	var imgCollapse = webRoot+"images/smallicons/collapse.gif";
	var imgExpand = webRoot+"images/smallicons/expand.gif";
	if (curr == "none") {
		blockElement.style.display = "block";
		imageElement.src=imgCollapse;
	} else {
		blockElement.style.display = "none";
		imageElement.src=imgExpand;
	}
}

function manuallyMarkSpam(blogId, mark, updateUrl) {
   $('mark'+blogId).innerHTML = "Please wait! marking as "+mark+".";
   dojo.xhrGet({
            url: updateUrl,
            load: function(response, ioArgs){
                console.log("data received from "+updateUrl);
            },
            handleAs: "javascript"
  });
}

// Adjusts the dimension of the supplied node so that it does not exceeds
// the max width and height
function adjustDimensions(/*DomNode*/node, /*int*/maxWidth, /*int*/maxHeight, /*int*/ minWidth) {
    var sHeight = node.scrollHeight;
    var sWidth = node.scrollWidth;
    console.log("height and width are "+sHeight+" and "+sWidth+" for "+node+" with id "+node.id);
    // console.log("max height and width are "+maxHeight+" and "+maxWidth);
    if (sHeight > maxHeight) {
            // console.log("resizing to max height "+maxHeight);
            node.style.height = maxHeight + "px";
            node.style.overflow = "auto";
    }
    if (sWidth > maxWidth) {
            // console.log("resizing to max width "+maxWidth);
            node.style.width = maxWidth + "px";
            node.style.overflow = "auto";
    }
	if (sWidth < minWidth && sWidth > 1) {
            // console.log("resizing to min width "+minWidth);
            node.style.width = minWidth + "px";
    }
}

// gets the first child of the node which is a DIV
function getFirstDivChild(/*DomNode*/node) {
    var divChild = null;
    dojo.forEach(node.childNodes,
        function (child) {
            if (child.nodeName == "DIV") {
                if (divChild == null) {
                    divChild = child;
                }
            }
        });
    return divChild;
}

// This is a list of functions that need to be executed once the custom widget
// blogscope.Tooltip loads
var blogscopeLoaders = [];
// This variable is set to true after blogscope.Tooltip declaration finishes loading
var blogscopeTooltipLoaded = false;
// This function is similar to dojo.addOnLoad, but it ensures that the
// custom blogscope.Tooltip widget is loaded before the function call is made
blogscopeAddOnLoad = function (/*Function*/ f) {
    if (blogscopeTooltipLoaded) {
        console.log("Calling the function ", f);
        f();
    } else {
        console.log("Pushing the function to queue ", f);
        blogscopeLoaders.push(f);
    }
}


dojo.addOnLoad( function() {
    dojo.provide("blogscope.Tooltip");
    dojo.provide("blogscope.MasterTooltip");
    // A lot of code here was originaly copied from Tooltip.js in dojo source code, and then modified.
    // Refer to dijit/Tooltip.js for more documentation and explanation
    dojo.declare(
        // Each tooltip has a master tooltip which contains the actual content
        "blogscope.MasterTooltip",
        dijit._MasterTooltip,
        {
            // the fade in fade out duration
            duration: 50,
            parentTooltip: null,
            templateString: "<div id=\"dijitTooltip\" class=\"dijitTooltip dijitTooltipBelow\">\n\t<div class=\"dijitTooltipContainer dijitTooltipContents\" id=\"dijitTooltipContainer\" dojoAttachPoint=\"containerNode\" waiRole='alert'></div>\n\t<div class=\"dijitTooltipConnector blogscopeTooltipConnector\" id=\"tooltipConnector\"></div>\n</div>\n",
            show: function(/*DomNode*/ aroundNode){
				// console.log("Calling the show method with "+aroundNode);
				if(this.aroundNode && this.aroundNode === aroundNode){
	                return;
    	        }
                if(this.fadeOut.status() == "playing"){
                    // previous tooltip is being hidden; 
                    // wait until the hide completes then show new one
                    this._onDeck=arguments;
                    return;
                }
                this.containerNode.innerHTML=this.parentTooltip.label;
                // Firefox bug. when innerHTML changes to be shorter than previous
                // one, the node size will not be updated until it moves.
                this.domNode.style.top = (this.domNode.offsetTop + 1) + "px";
    
                var align = {'BL' : 'TL'};
                var pos = dijit.placeOnScreen(this.domNode, {x: this.parentTooltip.mouseX, y: this.parentTooltip.mouseY}, ["TL"]);
                this.domNode.className="dijitTooltip dijitTooltipBelow blogscopeTooltip";
    
                // show it
                dojo.style(this.domNode, "opacity", 0);
                this.fadeIn.play();
				this.aroundNode = aroundNode;
                // In our template string, we have 3 div nodes nested in one another
                // for asthetic reasons, we chose to adjust dimension of the innermost DIV
                var adjustNode = getFirstDivChild(getFirstDivChild(this.domNode));
                adjustDimensions(adjustNode, this.parentTooltip.maxWidth, this.parentTooltip.maxHeight, this.parentTooltip.minWidth);
				dojo.parser.parse(this.containerNode);
            },
            // refresh the contents of the tooltip
            refresh: function() {
                this.containerNode.innerHTML=this.parentTooltip.label;
				// console.log("Calling refresh with "+this.aroundNode);
                if (this.aroundNode) {
                    var adjustNode = getFirstDivChild(getFirstDivChild(this.domNode));
                    adjustDimensions(adjustNode, this.parentTooltip.maxWidth, this.parentTooltip.maxHeight, this.parentTooltip.minWidth);
					dojo.parser.parse(this.containerNode);
                }
            },
            // called once after creation of the widget
            postCreate: function(){
                dojo.body().appendChild(this.domNode);
                this.bgIframe = new dijit.BackgroundIframe(this.domNode);
                // I wanted to set a unique id for the domNode, but getUniqueId does not work with IE6
                // If the line below is uncommented, it prints error in IE6
                // this.domNode.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
                // Setup fade-in and fade-out functions.
                this.fadeIn = dojo.fadeIn({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onShow") });
                this.fadeOut = dojo.fadeOut({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onHide") });
                // connect the event of mouse moving out
                this.connect(this.domNode, "onmouseout", "_onMouseOut");
            },
            // when mouse moves out
            _onMouseOut: function(/*Event*/ e){
                this.parentTooltip._onMouseOut(e);
            }
        }
    );
    // blogscope.Tooltip is the main widget that we will use
    dojo.declare(
        "blogscope.Tooltip",
        dijit.Tooltip,
        {
            // false if the contents are yet to be loaded from the HTTP request
            hasLoaded: false,
            // location from where to fetch the contents
            href: "",
            // max height and width of the tooltip
            maxWidth: 480,
            maxHeight: 450,
            minWidth: 0,
			// what to send to urchin tracker?
			urchinLog: null,
            // the position of mouse when the tooltip is created
            mouseX: 0,
            mouseY: 0,
            // contents to diplay in the tooltip. Initialized to a loading icon.
            label: "<div><img src=\""+webRoot+"images/loading.gif\"> Loading...</div>",
            masterTooltip: null,
            loadContent: function() { 
                if (this.hasLoaded == false) {
                    this.hasLoaded = true;
                    dojo.xhrGet({
                        url: this.href,
                        parentTooltip: this,
                        load: function(response, ioArgs){
                            // console.log("data received from ", this.url);
                            // console.log("parent is "+this.parentTooltip);
                            this.parentTooltip.label = response;
                            this.parentTooltip.minWidth=400;
                            this.parentTooltip.masterTooltip.refresh();
							if (this.parentTooltip.urchinLog != null) {
								urchinTracker(this.parentTooltip.urchinLog);
							}
                        },
                        handleAs: "text"
                    }); 
                }
            },
            open: function(/*DomNode*/ target){
				target = target || this._connectNodes[0];
				if (!target) {
					console.log("invalid target for opening the tooltip");
					return;
				}
				// console.log("tooltip open called with target "+target);
                if (this.masterTooltip == null) {
                    // initialized the master tooltip
                    this.masterTooltip = new blogscope.MasterTooltip({parentTooltip: this});
                }
                this.loadContent();
                if(this._showTimer){
                    clearTimeout(this._showTimer);
                    delete this._showTimer;
                }
				this._connectNode = target;
                this.masterTooltip.show(this._connectNode);
            },
            close: function(){
				// console.log("Calling the close function on tooltip");
                if (this.masterTooltip != null) {
                    this.masterTooltip.hide(this._connectNode);
                }
				delete this._connectNode;
				if (this._showTimer) {
					clearTimeout(this._showTimer);
					delete this._showTimer;
				}
            },
            _onMouseOut: function(/*Event*/ e){
                // currXD and Y are current position of the mouse
                var currX = e.pageX;
                var currY = e.pageY;
                // this.mouseX and this.mouseY are the top-left corners of the tooltip
                var posOffset = Math.abs(this.mouseX - e.pageX) + Math.abs(this.mouseY - e.pageY);
                // console.log("Mouse out called with ",e);
                // we allow mouse movement of 15px
                if (posOffset < 16) {
                    return;
                }
                if(dojo.isDescendant(e.relatedTarget, e.target)){
                     // false event; just moved from target to target child; ignore.
                    return;
                }
                if (this.masterTooltip != null) {
                    // get coordinates and dimensions of the actual tooltip contents
                    var c = dojo.coords(this.masterTooltip.domNode);
                    // console.log("Tooltip coordinates", c, "Curr", currX, currY, "MouseXY", this.mouseX, this.mouseY);
                    if (this.mouseX < currX && this.mouseX + c.w > currX && this.mouseY < currY && this.mouseY + c.h > currY) {
                        // the mouse is still on the tooltip contents, no need to close it
                        return;
                    }
                }
                // close the tooltip
                this._onUnHover(e);
            },
            _onHover: function(/*Event*/ e){
                // find the current mouse postion, the top-left corner of the tooltip will be here
                this.mouseX = e.pageX;
                this.mouseY = e.pageY;
                // console.log("Mouse X,Y is "+this.mouseX+", "+this.mouseY);
                // If tooltip not showing yet then set a timer to show it shortly
				if (!this._showTimer) {
					this._showTimer = setTimeout(dojo.hitch(this, function() {this.open(e.target)}), this.showDelay);
				}
            },
            _onMouseOver: function(/*Event*/ e){
                this._onHover(e);
            }
        }
    );
	// finished loading blogscope.Tooltip declaration
	
	console.log("finished loading the definition of blogscope custom widget");
	// we have finished declaration of the widget
    // now exectute all functions that were waiting for the custom widget to load
    blogscopeTooltipLoaded = true;
    dojo.forEach(blogscopeLoaders,
        function(f) {
            f();
        }
    )
}
);

function toast(msg /*String*/) {
	dojo.publish("infoToast", 
				[{
					message: msg
				}]
			);
}

function toastError(msg /*String*/) {
	dojo.publish("infoToast", 
				[{
					message: msg,
					type: 'error'
				}]
			);
}

function showSummary(time /*long*/, blogid /*int*/, numSentences /*int*/, nodeid /*string*/) {
	console.log("summarize blogid, time, numSentences, nodeid ",blogid, time, numSentences, nodeid);
	var node = dojo.byId(nodeid);
	node.style.display = "block";
	DWRMethods.summarize(blogid, time, numSentences, function(data) {
		var summary = "<b>Summary:</b> ";
		dojo.forEach(data, function (line) {
			summary = summary + " " + line;
		});
		node.innerHTML = summary;
	});
}

function showSentiment(time /*long*/, blogid /*int*/, nodeid /*string*/) {
	console.log("sentiment blogid, time, numSentences, nodeid ",blogid, time, nodeid);
	var node = dojo.byId(nodeid);
	node.style.display = "block";
	DWRMethods.sentimentInfo(blogid, time, function(data) {
		node.innerHTML = data;
	});
}

function load(url /*String*/) {
	if (url == null) {
		alert('unable to load the document');
	} else {
		console.log("Loading "+url);
		window.location.href=url;
	}
}

// For creation of required doc (HTML/PDF/NONE), a base url of the page is required
var baseurlHtml = window.location.href;
var baseurlPdf = window.location.href;
var baseurlCsv = null;

// format is one of html, pdf, or csv
function getDocBaseUrl(format /*string*/) {
	if (format == 'pdf') {
		return addArgToUrl(baseurlPdf, "docFormat", format);
	} else if (format == 'html') {
		return addArgToUrl(baseurlHtml, "docFormat", format);
	} else if (format == 'csv') {
		return baseurlCsv;
	}
	return null;
}

function addArgToUrl(url /*String*/, key /*String*/, val /*String*/) {
	if (url.indexOf("?") > 0) {
		return url + "&" + key + "=" + escape(val);
	} else {
		return url + "?" + key + "=" + escape(val);
	}
}

// format is one of html, pdf, or csv
function getDocExportUrl(format /*string*/) {
	if (getDocBaseUrl(format) == null) {
		return null;
	}
	return webRoot + "dimg/docexporter.jsp?format="+format+"&url="+escape(getDocBaseUrl(format));
}

function disableDocExport() {
	dojo.addOnLoad(function() {
		try {
			var widget1 = dijit.byId("menuDownloadPDF");
			if (widget1) {
				widget1.setDisabled(true);
			}
			var widget2 = dijit.byId("menuEmail");
			if (widget2) {
				widget2.setDisabled(true);
			}
		} catch (err) {
			console.error("Error "+err);
		}
	});
}

function exportAndSendMail(userid /*string*/) {
    var msgDisplayNode = dojo.byId('exportDialogMessage');
	msgDisplayNode.style.display = "block";
	msgDisplayNode.innerHTML = "<p><img src='"+webRoot+"images/loading.gif'> Loading... Please wait, and do not reload or press Send Mail button again.</p>";
	try {
	var formValues = dijit.byId('exportDialogForm').getValues();
	var fromName = formValues['fromName'];
	var fromEmail = formValues['fromEmail'];
	var to = formValues['to'];
	var subject = formValues['subject'];
	var text = formValues['text'];
	var format = formValues['format'];
	var url = getDocBaseUrl(format);
	var displayName = null;
	DWRMethods.exportAndSendMail(to, fromName, fromEmail, subject, text, url, format, userid, displayName, function(data){
		console.log("Received data back from DWR", data);
		if (data == null) {
			data = "Sucess, the email has been sent successfully.";
		}
		msgDisplayNode.style.display = "block";
		msgDisplayNode.innerHTML = "<p>"+data+"</p>";
	});
	console.log("Made DWR call to send mail to "+to +" for "+url +" in "+format +" format");
	} catch (e) {
		console.log("Error "+e);
		msgDisplayNode.innerHTML = "<p>Error in sending the email!</p>";
	}
}

blogscopeAddOnLoad( function() {
	function checkOpentooltips(e /*Event*/) {
		console.log("Calling checkopentooltips");
		try {
			dojo.query(".dijitTooltip").forEach (
				function(node) {
					var widgetId = node.getAttribute("widgetid");
					var widget = dijit.byId(widgetId);
					if (widget) {
						try {
							var parentTooltip = widget.parentTooltip;
							if (parentTooltip) {
								// console.log("parent tooltip is "+parentTooltip);
								parentTooltip._onMouseOut(e);
							}
						} catch (err) {
							console.log("Error " + err);
						}
					}
				}
			);
		} catch (err) {
			console.log("Error ",err);
		}
	}	
	dojo.query("body").forEach(
		function(node) {
			dojo.connect(node, "onclick", checkOpentooltips);
		}
	);
});

function loadSidebar(/* boolean */ show) {
	var node = $('sidebarTD');
	if (show) {
		if (node.style.display == "block" ){
			return;
		}
		node.style.display = "block";
	 	// node.style.width = "200px";
		//node.style.margin = "0px";
		//node.style.padding = "0px";
		// $('mainbodytable').style.width = "100%";
		dojo.animateProperty({ node: node, duration:500,
	    	properties: {
    	    	width: { start: '100', end: '200', unit:"px" }
    		}
    	}).play();
		dojo.query(".saveImage").forEach(
			function(saveImageNode) {
				saveImageNode.style.display = "block";
			}
		);
		updateFolderContents();
	} else {
		node.style.display = "none";
		node.style.width = "0px";
		dojo.query(".saveImage").forEach(
			function(saveImageNode) {
				saveImageNode.style.display = "none";
			}
		);
	}
}


function updateFolderContents() {
	var selectNode = $("folderselect");
	if (selectNode.options.length == 0) {
		console.log('not updating folder contents (zero folders found)');
		return;
	}
	var folderid = selectNode.options[selectNode.selectedIndex].value;
	console.log('updating folder contents for '+folderid);
	dojo.xhrGet({
    	url: webRoot + "tools/folders/foldercontents.jsp?folderid="+folderid,
        load: function(response, ioArgs){
	       	var cnode = $("foldercontents");
    	   	cnode.innerHTML = response;
        	highlight(selectNode);
		},
        handleAs: "text"
    });
}

function confirmationDialog(msg /*String*/, action /*String to Eval*/) {
	if(confirm(msg)) {
		eval(action);
	}
}

/* functions for loading icon display */

function setLoading(val /*boolean*/) {
	try {
		if (val) {
			$("main-loading").style.display="block";
		} else {
			$("main-loading").style.display="none";
		}
	} catch (err) {
		console.error("error "+err);
	}
}

var loadingCount = 0;

function pushLoading() {
	loadingCount += 1;
	console.log("push loading with count now "+loadingCount);
	if (loadingCount > 0) {
		setLoading(true);
	}
}

function popLoading() {
	loadingCount -= 1;
	console.log("pop loading with count now "+loadingCount);
	//if (loadingCount < 0) {
	//	loadingCount = 0;
	//}
	if (loadingCount == 0) {
		setLoading(false);
	}
}

blogscopeAddOnLoad(function() {
		popLoading();
});

function trackConversations(blogid /*int*/, time /*long*/, nodeid /*string*/) {
	console.log("Loading conversations for "+blogid+", "+time+", in "+nodeid);
	var node = $(nodeid);
	showAndAnimate(node);
	var trackerUrl = webRoot + "ajax/conversationTracker.jsp?blogid="+blogid+"&time="+time;
	dojo.xhrGet({
		url: trackerUrl,
		error: function(data) {
			node.innerHTML = "Error in fetching conversations";
			console.log("error "+data);
		},
		load: function(response, ioArgs) {
			node.innerHTML = response;
		},
		handleAs: 'text'
	});
}

function trackComments(blogid /*int*/, time /*long*/, nodeid /*string*/) {
	console.log("Loading comments for "+blogid+", "+time+", in "+nodeid);
	var node = $(nodeid);
	showAndAnimate(node);
	var trackerUrl = webRoot + "ajax/commentsTracker.jsp?blogid="+blogid+"&time="+time;
	dojo.xhrGet({
		url: trackerUrl,
		error: function(data) {
			node.innerHTML = "Error in fetching comments";
			console.log("error "+data);
		},
		load: function(response, ioArgs) {
			node.innerHTML = response;
		},
		handleAs: 'text'
	});
}

function translate(srcNode /*DomNode Id*/, targetNode /*DomNode Id*/, fromLanguage /*String*/, toLanguage /*String*/) {
	var target = dojo.byId(targetNode);
    target.style.display="block";
    target.innerHTML = "Loading...";
    var alltext = dojo.byId(srcNode).innerHTML;
	if (fromLanguage == null || fromLanguage == "null") {
		var sinppet = alltext;
		if (alltext.length > 200) {
			// google lang detection hangs for large text lengths
			snippet = alltext.substring(0, 200);
		}
		console.log("text of length "+snippet.length+" submitted for language detection");
		google.language.detect(snippet, function(result) {
        	if (!result.error && result.language) {
				fromLanguage = result.language;
				toast("translating from " + fromLanguage + " to "+toLanguage);
    			translateHelper(alltext, targetNode, fromLanguage, toLanguage);
			} else {
				toastError("Error in language detection");
			}
		});
	} else {
		toast("translating from " + fromLanguage + " to "+toLanguage);
    	translateHelper(alltext, targetNode, fromLanguage, toLanguage);
	}
}

function translateHelper(alltext /*String*/, targetNode /*DomNode Id*/, fromLanguage /*String*/, toLanguage /*String*/) {
	if (alltext.length < 5) {
        return;
    }
	var maxLen = 200;
	if (fromLanguage != null) {
		fromLanguage = fromLanguage.toLowerCase();
	}
	if (fromLanguage == "en" || fromLanguage == "es" || fromLanguage == "de" || 
				fromLanguage == "fr" || fromLanguage == "pt" ) {
		// for ASCII langs we can use larger limit
		maxLen = 490;
	}
    var target = dojo.byId(targetNode);
		var text = alltext;
		if (text.length > maxLen) {
            text = text.substring(0, maxLen);
    	} 
        alltext = alltext.substring(text.length, alltext.length);
	    console.log("text of length "+text.length+" submitted for translation");
        googleTranslate(text, fromLanguage, toLanguage,
           function(result) {
               if (result.translation) {
	    		   if (target.innerHTML == "Loading...") {
                       target.innerHTML = result.translation;
                   } else {
                       target.innerHTML += result.translation;
                   }
				   translateHelper(alltext, targetNode, fromLanguage, toLanguage);
               } else {
                   toastError("Error in translating");
              }
        });
}

// use google api to translate the text from fromlanguage (which can be null) to toLanguage. If fromLanguage 
// is null or "null", then the language detect function from google api is used.
function googleTranslate(text, fromLanguage, toLanguage, callbackFunction) {
	if (fromLanguage == null || fromLanguage == "null") {
		console.log("submitted "+text.length+" chars for language detection");
		google.language.detect(text, function(result) {
        	if (!result.error && result.language) {
				console.log("received "+result.language+" as language");
				googleTranslate(text, result.language, toLanguage, callbackFunction);
			} else {
				toastError("Error in language detection");
			}
		});
	} else {
		google.language.translate(text, fromLanguage, toLanguage, callbackFunction);
	} 
}

console.log("finished loading the application.js");
