var Celebros_DataServerDNS = 'services.celebros.com';
var Celebros_WidgetsServerDNS = 'services.celebros.com';
var Celebros_ProductsJSONPage = '/JsonEndPoint/ProductsRecommendation.aspx';
var Celebros_ProductRecWidgetFile = '/Widgets/CelebrosProductRecommendationsWidget.js';
var Celebros_RequestType = 0;

var downloadedFiles = new Array();

var Celebros_DataRetrieved;
var Celebros_FirstCall = true;

//This allows trimming of strings without having to write out the function every time
String.prototype.trim = function() 
{
	return this.replace(/^\s+|\s+$/g,"");
}

// This function makes sure that the same file is included only once
function Celebros_includeOnce(sScriptFileName)
{
    if (downloadedFiles[sScriptFileName] != true) {
        downloadedFiles[sScriptFileName] = true;
        Celebros_include(sScriptFileName);
    }
}

// This function includes specified file
function Celebros_include(sScriptFileName)
{
    document.write('<sc' + 'ript');
    document.write(' language="javascript"');
    document.write(' type="text/javascript"');
    document.write(' id="CelebrosScript"');
    document.write(' src="' + sScriptFileName + '">');
    document.write('</sc' + 'ript>');
} 

// This function includes specified file
function Celebros_changeInclude(sScriptFileName)
{
    document.getElementById('CelebrosScript').setAttribute('src',sScriptFileName)
} 

// This function includes specified css file
function Celebros_includeCSS(sCSSFileName) 
{
    document.write('<l' + 'ink');
    document.write(' rel="stylesheet"');
    document.write(' type="text/css"');
    document.write(' href="' + sCSSFileName + '">');
}   

function Celebros_includeDOM(sScriptFileName) 
{
	var script = document.createElement('script');
	script.setAttribute('type', 'text/javascript');
    script.setAttribute('src', sScriptFileName);
	document.getElementsByTagName('head')[0].appendChild(script);
	return false;
}
 
// This function checks if the parameter is set 
function Celebros_isset(variable)
{
    return(typeof(variable)!='undefined');
}

// This method is passed to JSON page as a callback function
// and it's responsible for checking that the widget rendering function
// is already loaded and calling this function with the products recommendation result (JSON)
function Celebros_CallProductWidgetRenderer(ProductsRecommendationResult)
{
    if (typeof(Celebros_renderProductRecommendationsWidget) == 'undefined')
        throw "Product Recommendations Widget file wasn't loaded";
    Celebros_renderProductRecommendationsWidget(ProductsRecommendationResult)
}

            
// This functions gets recommended products from the recommendation engine
// and return JSON with the callback function call and the recommended products as a param
function Celebros_includeProductRecommendations(FunctionParams)
{
    var productsURL = Celebros_getHttpPrefix();
    
    productsURL += Celebros_GetProductsEndPointURL();
	    
	// add site key 
	productsURL = Celebros_addURLParam(productsURL, 'siteKey', Celebros_Params.SiteKey);

	// add place holder id
    productsURL = Celebros_addURLParam(productsURL, 'RequestHandle', Celebros_Params.Placeholder);
		
	// request type
	if (Celebros_isset(Celebros_Params.RequestType))
	    productsURL = Celebros_addURLParam(productsURL, 'RequestType', Celebros_Params.RequestType);
    else 		    
	    productsURL = Celebros_addURLParam(productsURL, 'RequestType', Celebros_RequestType);

	   
    // add product SKU (optional)
    if (Celebros_isset(Celebros_Params.SKU))    
        productsURL = Celebros_addURLParam(productsURL, 'SKU', Celebros_Params.SKU);

    
    // add page encoding (optional)   
    var Encoding = Celebros_getCharset();
    
    if (Celebros_isset(Encoding))
        productsURL = Celebros_addURLParam(productsURL, 'Encoding', Encoding);                
        
    if(FunctionParams) //Additional parameters, will be removed when all parameters will be passed directly. For now, this is used for paging and sorting
    {
        if(Celebros_isset(FunctionParams.Page))
            productsURL = Celebros_addURLParam(productsURL, 'Page', FunctionParams.Page);
        if(Celebros_isset(FunctionParams.Sorting))        
            productsURL = Celebros_addURLParam(productsURL, 'Sorting', FunctionParams.Sorting);
    }
	
//	// add number of products (optional)
//	if (Celebros_isset(Celebros_Params.NumOfProducts))
//		productsURL = Celebros_addURLParam(productsURL, 'NumOfProducts', Celebros_Params.NumOfProducts);
	
	productsURL = Celebros_addURLParam(productsURL, 'callback', 'Celebros_CallProductWidgetRenderer');
	
	if(Celebros_FirstCall)
	    Celebros_include(productsURL);
	else
	    Celebros_changeInclude(productsURL);
}

function Celebros_GetProductsEndPointURL()
{
    //if the user defined the dns in our parms
    if (Celebros_isset(Celebros_Params.DataServerDNS))
        return Celebros_Params.DataServerDNS + Celebros_ProductsJSONPage;
        
    //if we have the Conectivity object use it
    if (typeof CelebrosConectivity != 'undefined' &&
        Celebros_isset(CelebrosConectivity.DNS))
        return CelebrosConectivity.DNS + Celebros_ProductsJSONPage;
   
    //use the default 
	return Celebros_DataServerDNS + Celebros_ProductsJSONPage;
}

function Celebros_GetRecWidgetURL()
{
    //if the user defined the dns in our parms
    if (Celebros_isset(Celebros_Params.WidgetsServerDNS))
        return Celebros_getHttpPrefix() + Celebros_Params.WidgetsServerDNS + Celebros_ProductRecWidgetFile;
        
    //if we have the Conectivity object use it
    if (typeof CelebrosConectivity != 'undefined' &&
        Celebros_isset(CelebrosConectivity.DNS))
	    return Celebros_getHttpPrefix() + CelebrosConectivity.DNS + Celebros_ProductRecWidgetFile;
	
	//use the default     
    return Celebros_getHttpPrefix() + Celebros_WidgetsServerDNS + Celebros_ProductRecWidgetFile;
}

// This function encodes strings for URI
function Celebros_encodeURIComponent(str)
{
	if (typeof(encodeURIComponent) == 'function') 
	{
    	return encodeURIComponent(str);
	}
	else 
	{
    	return escape(str);
  	}
}

function Celebros_getCharset()
{
    //if we foraced encoding return it
    if(Celebros_isset(Celebros_Params.Encoding))
        return Celebros_Params.Encoding;  
    
    //IE -not utf-8 send the encoding
    if(Celebros_isset(document.charset) && document.charset.toLowerCase() != "utf-8")
         return document.charset;
    
    //FireFox -not utf-8 send the encoding
    if(Celebros_isset(document.characterSet) && document.characterSet.toLowerCase() != "utf-8")
         return document.characterSet;
         
    return;
} 

// This function adds params to URL string
function Celebros_addURLParam(sURL, sParamName, sParamValue)
{
	if (sParamName) 
	{
		sURL += (sURL.indexOf("?") == -1 ? "?" : "&");
		sURL += Celebros_encodeURIComponent(sParamName) + "=" + Celebros_encodeURIComponent(sParamValue);
	}
	return sURL;
}

// This function gets current http prefix
function Celebros_getHttpPrefix()
{
	if (window.location.protocol == "http:")
	{
    	sHttpPrefix = "http://";
	}
	else if (window.location.protocol == "https:")
	{
    	sHttpPrefix = "https://";
	}
	
	return sHttpPrefix;	
}

function isString (prop)
{
  return (typeof prop == 'string');
}


//check if Basic Params are defined or throw exception
function Celebros_checkBasicParams()
{
    if (!Celebros_isset(Celebros_Params))
	    throw "Celebros_Params is undefined";
	    
	if(!Celebros_isset(Celebros_Params.SiteKey))
	    throw "SiteKey is undefined";
	
	if(!Celebros_isset(Celebros_Params.Placeholder))
	    throw "Placeholder is undefined";     
	    
}

/**
 * Function to check that a string is harmless (no tag
 * injection).
 * @param value string Value to check.
 */
function validString(value) {
    return /^[^<>"]+$/.test(value);
}

/**
*function to go over all params to see that no string is potentially harmful(tag injection). 
*/
function Celebros_checkForInjection()
{
	for(var object_properties in Celebros_Params)
	{
	    if(isString(Celebros_Params[object_properties]) && !validString(Celebros_Params[object_properties]))
	        throw "parameter "+object_properties+ " is not valid"; 
    }
}


// This is the main function responsible for product recommendations widget generation
function Celebros_generateProductRecommendationsWidget(AdditionalParams) 
{
	try 
	{
	    Celebros_checkBasicParams(); 
	    Celebros_checkForInjection();   
        Celebros_includeOnce(Celebros_GetRecWidgetURL());	        
        if(AdditionalParams) //For now, this means this is a postback. This will need to be changed when parameters will always be passed
            Celebros_includeProductRecommendations(AdditionalParams);
        else if(Celebros_DataRetrieved) //Use "cached" data
	        Celebros_CallProductWidgetRenderer(Celebros_DataRetrieved);
	    else
	        Celebros_includeProductRecommendations();
	}
	catch(err)
    {
        if (typeof Celebros_Params != 'undefined' && Celebros_Params.IsDebug)
        {
            txt="There was an error on this page.\n\n";
            txt+="Error description: " + err + err.description + "\n\n";
            txt+="Click OK to continue.\n\n";
            alert(txt);
        }
    }
}

// This is the main function responsible for product recommendations widget generation
function Celebros_generateWidget(Celebros_Params) 
{
	try 
	{
	    Celebros_checkBasicParams(); 
	    Celebros_checkForInjection();   
        Celebros_includeOnce(Celebros_GetRecWidgetURL());	        
	    Celebros_includeProductRecommendations();
	}
	catch(err)
    {
        if (typeof Celebros_Params != 'undefined' && Celebros_Params.IsDebug)
        {
            txt="There was an error on this page.\n\n";
            txt+="Error description: " + err + err.description + "\n\n";
            txt+="Click OK to continue.\n\n";
            alert(txt);
        }
    }
}




//Celebros_includeCSS(Celebros_getHttpPrefix() + 'services.celebros.com/ProductRecommendations/CelebrosStyle.css');