/******************************* ahCalls Class **************************************************************/
//ahCalls.createAhCall("[get],[post],[scriptTag],[proxyGet],[proxyPost]", "url to web service or local file", "[string],[jsonObject],[jsonString],[xmlObject],[xmlString]", callback function name, "parameters if using post, if not set as false", "proxy path, false, or leave blank");

var boolRatingSubmitted = false;

var ahCalls = {
	
	theReturnType:null,
	called:false,
	queryStr:null,
	counter:0,
	scriptTagCallBackFunction:null,
	scriptTagJsonType:null,
	
	createAhCall:function(httpType,url,returnType,callBackFunction,params,proxyPath)
	{
		if(!document.getElementById || !document.createTextNode){return;}
		this.theReturnType = returnType;
		
		if(httpType != 'scriptTag'){//is not using script tag
			this.queryStr = (!params) ? null : encodeURIComponent(params);
			var xmlHttp = ahCalls.createXmlHttpObject();
			if (xmlHttp.readyState == 4 || xmlHttp.readyState == 0){// proceed only if the xmlHttp object isn't busy
				
				xmlHttp.onreadystatechange = function(){// define the method to handle server responses
				
					switch(xmlHttp.readyState){
						case 1: if(!this.called){/*alert('waiting on server!');*/this.called = true} break;
						case 2: break;
						case 3: break;
						case 4:
							if ( xmlHttp.status == 200 ){// only if "OK"
								try{
									responseObj = ahCalls.parseXmlHttpResponse(xmlHttp);
									success = true;
								}catch(e){ 
									alert('Parsing Error: The value returned could not be evaluated.');
									success = false;
								}
								if(success) callBackFunction( responseObj ); //if all is good send the response to the callback function
							}else{ 
								alert("There was a problem retrieving the data:\n" + xmlHttp.statusText);
							}
							break;
					}
				}
				
				if(httpType == 'get' || httpType == 'post'){
					xmlHttp.open(httpType, ahCalls.noCache(url), true);
				}else{
					if(httpType == 'proxyGet'){
						xmlHttp.open('get', (proxyPath+'?path='+(encodeURIComponent(url))), true);
					};
					if(httpType == 'proxyPost'){
						xmlHttp.open('put', (proxyPath+'?path='+(encodeURIComponent(url))), true);
					};
				}
				
				if(params){xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8")};
				xmlHttp.send(this.queryStr);// make the server request and send queryStr or null as an argument
				
			}else{// if the connection is busy, try again after one second 
				setTimeout('ahCalls.createAhCall();', 1000);
			}
		}else{//using scriptTag
			this.scriptTagCallBackFunction = callBackFunction;
			if(returnType == 'jsonObject' || returnType == 'jsonString'){//getting json return via script tag
			    //alert('jsonObject or jsonString');
				ahCalls.JsonXmlScriptRequest(ahCalls.noCache(url+'&callback=ahCalls.JsonXmlScriptHandleRequest'));
			}else{//getting xml return via script tag
				var xmlPath = encodeURIComponent(url);
				ahCalls.JsonXmlScriptRequest(proxyPath+'?path='+xmlPath);
			}
		}	
	},
	
	createXmlHttpObject:function()
	{
		var ahCalls; // will store the reference to the XMLHttpRequest Object
		
		try{
			ahCalls = new XMLHttpRequest();// this should work for all browsers except IE6 and older
		}catch(e){
			var XmlHttpVersions = new Array('MSXML2.XMLHTTP.6.0','MSXML2.XMLHTTP.5.0','MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP','Microsoft.XMLHTTP');
			for (var i=0; i<XmlHttpVersions.length && !ahCalls; i++) {
				try { 
					// try to create XMLHttpRequest object
					ahCalls = new ActiveXObject(XmlHttpVersions[i]);
				}catch (e) {}
			}
		}
		
		if(!ahCalls){alert("Error creating the XMLHttpRequest Object.")}else{return ahCalls};// return the created object or display an error message		
	},
	
	JsonXmlScriptRequest:function(fullUrl)
	{
		//alert('Inside JsonXmlScriptRequest()');
		ahCalls.counter += 1;
		var scriptId = 'JscriptId' + ahCalls.counter;
		
		var scriptObj = document.createElement("script");// Create the script tag
		
    	scriptObj.setAttribute("type", "text/javascript");   // Add script object attributes
		scriptObj.setAttribute("charset", "utf-8");
		scriptObj.setAttribute("src", fullUrl);
		scriptObj.setAttribute("id", scriptId);
		
		var headLoc = document.getElementsByTagName("head").item(0);
		headLoc.appendChild(scriptObj);
	},
	
	JsonXmlScriptHandleRequest:function(jsonData)
	{
		//alert('Inside JsonXmlScriptHandleRequest()');
		switch(ahCalls.theReturnType) {
		case "xmlObject": var xmlDataObject = ahCalls.xmlTextToObject(jsonData); ahCalls.scriptTagCallBackFunction(xmlDataObject);break;
		case "xmlString": ahCalls.scriptTagCallBackFunction(jsonData); break;
		case "jsonObject": ahCalls.scriptTagCallBackFunction(jsonData); break;
		case "jsonString": /*var jsonDataString = jsonData.toJSONString();ahCalls.scriptTagCallBackFunction(jsonDataString);*/ break;
		default: 
			// if there is no case "*" match, execute this code
			alert("error")
		};
		
		var scriptElement;
		for (var i = 1; i < 10; i++) {
			scriptElement = document.getElementById('JscriptId' + i);
			if(scriptElement){
			document.getElementsByTagName("head")[0].removeChild(scriptElement);
			}
		}
	},
	
	parseXmlHttpResponse:function(responseObject){
		var theType = ahCalls.theReturnType;
		if(theType != 'proxyPost' || theType != 'proxyGet'){//local xhr call
			switch(theType) {
			case "string": return responseObject.responseText; break;
			case "xmlObject": return responseObject.responseXML; break;
			case "xmlString": return responseObject.responseText; break;
			case "jsonObject": return responseObject.responseText.parseJSON();break;
			case "jsonString": return responseObject.responseText; break;
			default: 
				// if there is no case "*" match, execute this code
				alert("error")
			}
		}else{
			switch(theType) {//cross domain xhr to proxy and then back again
			case "xmlObject": return responseObject.responseXML; break;
			case "xmlString": return responseObject.responseText; break;
			case "jsonObject": return responseObject.responseText.parseJSON();break;
			case "jsonString": return responseObject.responseText; break;
			default: 
				// if there is no case "*" match, execute this code
				alert("error")
			}
		}
	},
	
	xmlTextToObject:function(text){
		if (typeof DOMParser != "undefined") {
		// Mozilla, Firefox, and related browsers
		return (new DOMParser()).parseFromString(text, "application/xml");
		}
		else if (typeof ActiveXObject != "undefined") {
			// Internet Explorer.
			var doc = new ActiveXObject("MSXML2.DOMDocument");  // Create an empty document
			doc.loadXML(text);            // Parse text into it
			return doc;                   // Return it
		}
		else {
			// As a last resort, try loading the document from a data: URL
			// This is supposed to work in Safari.
			var url = "data:text/xml;charset=utf-8," + encodeURIComponent(text);
			var request = new XMLHttpRequest();
			request.open("GET", url, false);
			request.send(null);
			return request.responseXML;
		}
	},
	
	noCache:function (url){
		//alert('Inside noCache()');
		var qs = new Array();
		var arr = url.split('?');
		var scr = arr[0];
		if(arr[1]) qs = arr[1].split('&');
		qs[qs.length]='nocache='+new Date().getTime();
		//alert(scr+'?'+qs.join('&'));
		return scr+'?'+qs.join('&');
	}

};
/************************************* end of ahCalls.js *******************************************************/
/*
    json.js
    2006-09-27

    This file adds these methods to JavaScript:

        object.toJSONString()

            This method produces a JSON text from an object. The
            object must not contain any cyclical references.

        array.toJSONString()

            This method produces a JSON text from an array. The
            array must not contain any cyclical references.

        string.parseJSON()

            This method parses a JSON text to produce an object or
            array. It will return false if there is an error.

    It is expected that these methods will formally become part of the
    JavaScript Programming Language in the Fourth Edition of the
    ECMAScript standard.

(function () {
    var m = {
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        },
        s = {
            array: function (x) {
                var a = ['['], b, f, i, l = x.length, v;
                for (i = 0; i < l; i += 1) {
                    v = x[i];
                    f = s[typeof v];
                    if (f) {
                        v = f(v);
                        if (typeof v == 'string') {
                            if (b) {
                                a[a.length] = ',';
                            }
                            a[a.length] = v;
                            b = true;
                        }
                    }
                }
                a[a.length] = ']';
                return a.join('');
            },
            'boolean': function (x) {
                return String(x);
            },
            'null': function (x) {
                return "null";
            },
            number: function (x) {
                return isFinite(x) ? String(x) : 'null';
            },
            object: function (x) {
                if (x) {
                    if (x instanceof Array) {
                        return s.array(x);
                    }
                    var a = ['{'], b, f, i, v;
                    for (i in x) {
                        v = x[i];
                        f = s[typeof v];
                        if (f) {
                            v = f(v);
                            if (typeof v == 'string') {
                                if (b) {
                                    a[a.length] = ',';
                                }
                                a.push(s.string(i), ':', v);
                                b = true;
                            }
                        }
                    }
                    a[a.length] = '}';
                    return a.join('');
                }
                return 'null';
            },
            string: function (x) {
                if (/["\\\x00-\x1f]/.test(x)) {
                    x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
                        var c = m[b];
                        if (c) {
                            return c;
                        }
                        c = b.charCodeAt();
                        return '\\u00' +
                            Math.floor(c / 16).toString(16) +
                            (c % 16).toString(16);
                    });
                }
                return '"' + x + '"';
            }
        };

    Object.prototype.toJSONString = function () {
        return s.object(this);
    };

    Array.prototype.toJSONString = function () {
        return s.array(this);
    };
})();

String.prototype.parseJSON = function () {
    try {
        return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
                this.replace(/"(\\.|[^"\\])*?"/g, ''))) &&
            eval('(' + this + ')');
    } catch (e) {
        return false;
    }
};
*/
/************ Implementatino ******************/
var ratings = new Array;
var id_prefix = "rating_star_";
var ratingSiteID = document.getElementById('ratingSiteId').title;
var articleID = document.getElementById('documentId').value;
var url_id = document.getElementById('rating_url');
var url;
var rating_username = null;

/**
 * Use 'url_id' to retrieve url for image Gallery related resources
 * otherwise use 'window.location'
 */
if (typeof(url_id) == 'undefined' || url_id == null ) {
    url = window.location;
} else {
	url = url_id.value;
}

/**
 * Cookies util 
 */
var ckUtil_visitorinfo =  new CJL_CookieUtil("visitorinfo",0,"/",".nasa.gov");
var ckUtil_ratinginfo  =  new CJL_CookieUtil("ratinginfo",1440*90,"/",".nasa.gov"); //TODO : put the apporiate TTL in min.

//if the "visitorinfo" exists, extract a value for a username.
if(ckUtil_visitorinfo.cookieExists()){
	//alert("visitorinfo exists");
	rating_username = ckUtil_visitorinfo.getSubValue("name");
} 

if(rating_username == null || rating_username == '') {
	rating_username = 'Guest';
}

/**
 * Get partial url for the image
 */
var partialImgUrl = function(path) {
    return path.substr(0, (path.length - 5));
}
/**
 * Control a hovering action.
 */
function hoverRating(index,rating) {
	if(!boolRatingSubmitted){
		var i;
		ratings[0] = rating;
		for (z=1;z<=5;z++) {
			i = document.getElementById(id_prefix + z);
			partial_img_src = partialImgUrl(i.getAttribute("src"));
			if (z <= index) {
				usei = partial_img_src + "2.gif";
			} else {
				usei = partial_img_src + "3.gif";
			}
			i.setAttribute("src", usei);
		}
	}
}

/**
 * Controls an unhovering action.
 */
function unhoverRating(index) {
	var i;
	for (z=1; z<=5; z++) {
		i = document.getElementById(id_prefix + z);
		partial_img_src = partialImgUrl(i.getAttribute("src"));
		usei = (ratings[0] >= z) ? partial_img_src + "1.gif" : partial_img_src + "0.gif";
		i.setAttribute("src", usei);
	}
}

/**
 * For Generating alt tag text.
 */
var getImageAltText = function(index) {
	if(index<2) return document.getElementById(id_prefix + 1).getAttribute("alt")
	if(index<3) return document.getElementById(id_prefix + 2).getAttribute("alt")
	if(index<4) return document.getElementById(id_prefix + 3).getAttribute("alt")
	if(index<5) return document.getElementById(id_prefix + 4).getAttribute("alt")
	if(index<6) return document.getElementById(id_prefix + 5).getAttribute("alt")
	return "";
}

/**
 * To disable to submission.
 *		parameters: average = avg. rating.
 *					mode    = 1 (No more rating submission)
 *							= 2 (Already Submitted)
 */
function disableRatingSubmission(average,mode) {
	//alert("disableRatingSubmission("+average+", "+mode+")");
	var alt = getImageAltText(average);
	switch(mode){
		case 1 : break;
		case 2 : alt = "Thank you for rating.";break;
		default: alert("invalid argument");
	}

	var i;
    var tabIdx;

    var submitted_rating = ckUtil_ratinginfo.getSubValue(articleID+'_r_');
	if(submitted_rating != null){
		//alert("Using stored rating.");
		average = submitted_rating;
	}


	for (itrz=1;itrz<=5;itrz++) {
		i = document.getElementById(id_prefix + itrz);
		tabIdx = document.getElementById(id_prefix + 'tab_' + itrz);
        

		partial_img_src=partialImgUrl(i.getAttribute("src"));
		
		if(itrz <= average)
			usei = partial_img_src + "6.gif";
		else
			usei = partial_img_src + "0.gif";
		i.setAttribute("src", usei);
		i.setAttribute("onmouseover", null);
		i.setAttribute("onmouseout", null);
		i.setAttribute("onclick", null);
		i.setAttribute("title",alt);
		i.setAttribute("alt",alt);
		i.setAttribute("class","star_inactive");

        if(tabIdx != null){
            tabIdx.setAttribute("href", "#");
            tabIdx.setAttribute("onfocus", null);
            if(itrz == 1 || itrz == 5)
            tabIdx.setAttribute("onblur", null);
        }

	}
	changeRatingSnippet(average);
}

 /**
  * Return "true" if the user has already submitted the rating, otherwise false.
  */
var isSubmitted = function(articleID){
	//alert("isSubmitted("+articleID+")");
	if(rating_username == ckUtil_ratinginfo.getSubValue('username') && articleID == ckUtil_ratinginfo.getSubValue("'"+articleID+"'")){
		//alert("username = "+ckUtil_ratinginfo.getSubValue('username')+" isSubmitted()= true");
		return true;
	} else{
		//alert("Username = "+rating_username+" isSubmitted()= false");
	    return false;
	}
}

/**
 * Store the value in a cookie.
 */
var insertSubValuesInCookie = function(rating){
	//alert("insetSubValueInCookie() articleID = "+articleID+" rating = "+rating);
	ckUtil_ratinginfo.setSubValue("username",rating_username);
	ckUtil_ratinginfo.setSubValue("'"+articleID+"'",articleID);
	ckUtil_ratinginfo.setSubValue(articleID+'_r_',rating);
	//alert("Checking : "+articleID +" = "+ckUtil_ratinginfo.getSubValue("'"+articleID+"'")+" Rating = "+ckUtil_ratinginfo.getSubValue(articleID+'_r_'));
}

/**
 * Submit rating
 */
function submitRating(rating) {
	try{
                var title = document.getElementById("titleUrl").value;
                boolRatingSubmitted = true;
		if(typeof(rating_username) == 'undefined' || rating_username == null)
			rating_username = 'Guest';
		var full_url = 'http://comments-submit.nasa.gov/rating/rating.jsp?siteID='+ratingSiteID+'&docID='+articleID+'&userRating='+rating+'&username='+rating_username+'&url='+url+'&title='+title;
		//alert(full_url);
		ahCalls.createAhCall('scriptTag', full_url, 'jsonObject', '', false);
		
		// call this if the average star(s) are shown after submission.
		//disableRatingSubmission(ratingData[3],2);

		// Call this if the user submit rating is shown after submission.
        disableRatingSubmission(rating,2);
		

		insertSubValuesInCookie(rating);
	} catch (e) {
		//alert("Error while submitting rating.");
	}
}

/**
 * Calculates and Renders the Average Snippet after rating submission.
 */
function changeRatingSnippet(rating) {
	try	{
		var txt_ele = document.getElementById("rating_avg_txt");
		// defense validation check
		if (typeof (txt_ele) == "undefined" || rating == null || rating == "") {
			return;
		}
		var snippet = txt_ele.innerHTML;
		if(typeof (ratingData) != "undefined" && ratingData != null && ratingData != ""){
			var before_avg = parseFloat(ratingData[4]);
			var before_count = parseInt(ratingData[6]);
			var rate = parseInt(rating);
			var after_count = before_count + 1;
			var after_avg = ((before_avg *  before_count) + rate )/after_count;
			after_avg = after_avg.toPrecision(2);
			if (after_count > 0 && after_avg > 0) {
				snippet = snippet.replace(ratingData[6],after_count);
				snippet = snippet.replace(ratingData[4],after_avg+'');
			}
		} else {
			snippet = 'Average Rating: '+ parseInt(rating).toPrecision(2) +' / 5 (1 ratings)';
		}
		//alert(snippet);
		txt_ele.innerHTML = snippet;
	}
	catch (e) {
		// alert(e);
		// do nothing
	}
}

/**
 * Logic to Renders the Rating UI.
 */

// Global Default: true = enable, false = disable.
var isDefaultOn = true;
var rating_avg = document.getElementById('rating_avg');
var ratingData = null;

/** 
 * Grab a data pretaining to the articleID,
 * if it doesn't exist, keep as a null.
 */
try	{
	ratingData = eval('ratingData'+articleID);
	if (ratingData == articleID) {
		ratingData = null;
	}
}
catch (e) {
    //alert(e);	 
}

if(isDefaultOn){
	//alert("Global Default is ON");
	if(typeof (ratingSiteData) != "undefined" && ratingSiteData != null){
		if(typeof (ratingData) != "undefined" && ratingData != null && ratingData != ""){
			if(ratingSiteData[1] == 'Y'&& ratingData[2] == 'Y'){
				if(ratingSiteData[2] == 'Y' && ratingData[3] == 'Y'){
					//alert("Avg and Submission are both enable.");
					rating_avg.innerHTML=ratingData[5];
                    
					// Disable if it is already submitted.
					if(isSubmitted(ratingData[1])){
						disableRatingSubmission(ratingData[4],2);
					}
				} else {
					//alert("Avg is enable but not the submission(either site or article level.");
					rating_avg.innerHTML=ratingData[5];
					//call a function to disable the submission.
					disableRatingSubmission(ratingData[4],1);
				}
			} 
		} else {
			//article level js doesn't exist.
			if(ratingSiteData[1] == "Y"){
				rating_avg.innerHTML=ratingSiteData[3];

				// Disable if it has been already submitted.
				if(isSubmitted(articleID)){
					disableRatingSubmission(0,2);
				}
			} else {
				//alert("Site Level disable");
			}
		}
	} else {
		//alert("ratingSiteData undefined. Please check.");
	}
} else {
	//alert("Global Default is OFF.");
}
