/**
 * -----------------------------------------------------------------
 * Copyright (c) 2000-2006 Fluid, Inc. All Right Reserved.
 * This software is the proprietary information of Fluid, Inc.
 * Use is subject to strict licensing terms.
 * -----------------------------------------------------------------
 *
 * concept_lib.js
 *
 * A Javascript library for the embed Concept Retail (TM) interactive
 * displays.
 *
 */

 /**
  * Embed a product viewer. This function will dynamically generate an OBJECT/EMBED
  * tag for the Flash player, unless Flash detection fails
  * 
  * @param params An object with the following properties:
  *  REQUIRED:
  *    - width                     The width of the product viewer.
  *    - height                    The height of the product viewer.
  *    - baseURL                   The base url of the conceptretail files.
  *    - customerId                The identifier of the customer.
  *    - productId                 The identifier of the given product to embed.
  *    - displayId                 The identifier of the display for this product (e.g. "detail").
  *  OPTIONAL: 
  *    - bgColor                   The background color of the viewer (e.g. #FFFFFF).
  *    - preloaderBgColor          The background color of the preloader (e.g. #FFCC00).
  *    - preloaderFgColor          The foreground color of the preloader (e.g. #FF0000).
  *    - preloaderMessage          The message to display below the preloader.
  *    - logFunction               The name of the Javascript function to invoke for logging. No parameter indicates no logging.
  *    - cacheControlId            An identifier that gets appended to pview / pviewer XML files to assist with cache issues (e.g. fall2004).
  *	   - wmode					   The transparency mode of the player. Valid values: "window", "transparent, or "opaque" (default).
  *    - displayControlXMLPath     The complete URL to the displayControl XML file. 
  *    - displayControlXML         A String representation of an XML config file (e.g "<display-control id=\"123\"> .... </display-control>").
  *    - noFlashImageURL           A URL to a fallback image to be used if the user doesn't have Flash.
  *    - onLoadHandler		The name of a JavaScript function that will handle an on load callback.
  *
  * 
  * @returns The DOM Element ID to the ProductViewer Flash for use with Javascript communication.
  */
 function embedProductViewer( params ) 
 {
 	var width = params.width;
	var height = params.height;
	
	var baseURL = params.baseURL;
	var productId = params.productId;
	var displayId = params.displayId;
	var customerId = params.customerId;
	var wmode = params.wmode || "opaque";
	
	if ( params.baseURL == null )
		params.baseURL = "";
	
	var noFlashImageURL = params.noFlashImageURL;
	if (noFlashImageURL == null)
		noFlashImageURL = baseURL + "customers/" + customerId + "/" + productId + "/" + productId + "_" + displayId + "/fallback.jpg";
		
	if ( hasFlash() )
	{
		// define our namespace
		if ( this.Concept == null )
			Concept = {}
		if ( Concept.registry == null )
		{
			Concept.registry = {}
			Concept.registry.ind = 1;
			Concept.registry.divInfo = {};
			Concept.registry.lastDisplayInfo = {};
		}
			
		Concept.registry.nextLCID = "CR_LCID_" + Concept.registry.ind++ + "_" + (new Date()).getTime();
		
		
		if ( params.baseURL != "" && params.baseURL.charAt( params.baseURL.length - 1 ) != "/" )
			params.baseURL += "/";
		var preloaderURL = params.baseURL + "standard/v2/swf/cengage_preloader.swf";
		var productViewURL = "../../../customers/" + customerId + "/" + productId + "/" + productId + "_" + displayId + 
							 "/pview_" + productId + "_" + displayId + ".xml";
		
	 	var bgColor = params.bgColor || "#FFFFFF";
	    var preloaderBgColor = params.preloaderBgColor || "#00CCFF";
	 	var preloaderFgColor = params.preloaderFgColor || "#0000FF";
	
		// change it to appropriate flash format
		preloaderBgColor = "0x" + preloaderBgColor.substring(1);
		preloaderFgColor = "0x" + preloaderFgColor.substring(1);
		
		var flashVars = 	'productViewXML=' + productViewURL; 
	 		flashVars += 	'&preloaderBGColor=' + preloaderBgColor;
			flashVars += 	'&preloaderFGColor=' + preloaderFgColor;
	 		flashVars +=	'&width=' + width;
	 		flashVars +=	'&height=' + height;
			flashVars +=	'&zoomWinLCID=' + Concept.registry.nextLCID;
			flashVars +=	'&htmlURL=' + window.location.host;
			flashVars +=	'&preloaderMessage=' + params.preloaderMessage;
		if ( params.logFunction != null )
			flashVars +=	'&logFunction=' + params.logFunction;
		if ( params.cacheControlId != null )
			flashVars +=	'&cacheControlId=' + params.cacheControlId;
		if ( params.displayControlXMLPath != null )
			flashVars +=	'&displayControlXMLPath=' + params.displayControlXMLPath;
		if ( params.displayControlXML != null )
			flashVars +=	'&displayControlInfo=' + escape( params.displayControlXML );
			
		if(params.onLoadHandler != null) flashVars += "&onLoadHandler=" + params.onLoadHandler;
		
		
		var elementId = "cengage_preloader_" + Concept.registry.ind;
		
		// IE VBScript to handle fscommands
		var scriptToWrite = '';
		scriptToWrite += '<script language="VBScript">';
		scriptToWrite += 'Sub ' + elementId + '_FSCommand(ByVal command, ByVal args)';
		scriptToWrite += 'call ' + elementId + '_DoFSCommand(command, args)';
		scriptToWrite += 'end sub';
		scriptToWrite += '</script>';
		document.writeln(scriptToWrite);
	
		// JavaScript method to handle fscommands
		this[elementId + "_DoFSCommand"] = function(command, args)
		{
			// Check for FSCommand: in the command/function name as is the case on the Mac
			if(command.indexOf("FSCommand:") == 0) command = command.split("FSCommand:")[1];
			var func = this[command];
			if(func != null) func(args);
		}
		
		var htmlFragment = "";
		htmlFragment += '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="' + width 
						+ '" height="' + height + 
						'" id="' + elementId + '" align="top">';
		htmlFragment += '<param name="movie" value="' + preloaderURL + '" />';
		htmlFragment += '<param name="allowScriptAccess" value="always" />';
		htmlFragment += '<param name="bgcolor" value="' + bgColor + '" />';
		htmlFragment += '<param name="base" value="." />';
		htmlFragment += '<param name="wmode" value="' + wmode + '" />';
 		htmlFragment += '<param name="flashvars" value="' + flashVars + '" />';
		htmlFragment += '<embed swliveconnect="true" src="' + preloaderURL + '" base="." quality="high" bgcolor="' + bgColor + 
						'" width="' + width +'" height="' + height + '"' + '"wmode="' + wmode + '"' +
						' name="' + elementId + '" align="top" allowScriptAccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"';
		htmlFragment +=	' flashvars="' + flashVars + '" >';
		htmlFragment += '</embed></object>';
	 	//alert(htmlFragment);
		document.writeln(htmlFragment);
		
		// track the info for the last display embed. needed for personalization
		var info = {};
		info.embedElementId = elementId;
		info.customerId = params.customerId;
		info.productId = params.productId;
		info.displayId = params.displayId;
		info.baseURL = params.baseURL;
		
		Concept.registry.lastDisplayInfo = info;
		
		return elementId;
	}
	else
	{
		document.writeln('<img src="' + noFlashImageURL +'" />');
	}
}

/**
 * Embed an external zoom window
 * 
 * @param params An associative array of the following parameters
 * REQUIRED:
 *     - baseURL            The baseURL of the conceptretail files.
 *	   - zoomWinX			The absolute x-pos of the external zoom window
 *	   - zoomWinY			The absolute y-pos of the external zoom window
 *	   - zoomWinWidth		The width of the external zoom window
 *	   - zoomWinHeight		The height of the external zoom window
 * OPTIONAL: 
 *     - bgColor            The background color of the viewer (default #FFFFFF).
 *	   - borderColor		The color of the border around the viewer (default #CCCCCC).
 */
function embedExternalWindowDiv( params )
{
	if ( hasFlash() )
	{
		if ( params.baseURL == null )
			params.baseURL = "";
		else
		{
			if ( params.baseURL != "" && params.baseURL.charAt( params.baseURL.length - 1 ) != "/" )
			params.baseURL += "/";
		}
		if ( params.bgColor == null )
			params.bgColor = "#FFFFFF";
		if ( params.borderColor == null )
			params.borderColor = "#CCCCCC";
	
		var externalWinURL = params.externalWinURL;
		var zoomWinX = params.zoomWinX;
		var zoomWinY = params.zoomWinY;
		var zoomWinWidth = params.zoomWinWidth;
		var zoomWinHeight = params.zoomWinHeight;
		var externalWinURL = params.baseURL + "standard/v2/swf/cengage_external_win.swf";  
		
		var flashVars = 'zoomWinLCID=' + Concept.registry.nextLCID;
 		flashVars +=	'&width=' + zoomWinWidth;
		flashVars +=	'&height=' + zoomWinHeight;
		flashVars +=	'&htmlURL=' + window.location.host;
		
		// store the position in a registry; we start with the div's offscreen
		Concept.registry.divInfo[ Concept.registry.nextLCID ] =  { x:zoomWinX, y:zoomWinY };
		
		var elementId = "cengage_external_win_" + Concept.registry.ind;
		
		// IE VBScript to handle fscommands
		var scriptToWrite = '';
		scriptToWrite += '<script ' + 'language="VBScript">';
		scriptToWrite += 'Sub ' + elementId + '_FSCommand(ByVal command, ByVal args)';
		scriptToWrite += 'call ' + elementId + '_DoFSCommand(command, args)';
		scriptToWrite += 'end sub';
		scriptToWrite += '</scr' + 'ipt>';
		document.writeln(scriptToWrite);
	
		// JavaScript method to handle fscommands
		this[elementId + "_DoFSCommand"] = function(command, args)
		{
			// Check for FSCommand: in the command/function name as is the case on the Mac
			if(command.indexOf("FSCommand:") == 0) command = command.split("FSCommand:")[1];
			var func = this[command];
			if(func != null) func(args);
		}
		
		var htmlFragment = "";
		htmlFragment += '<div id="' + Concept.registry.nextLCID + '" style="padding:0px;position:absolute; left:-10000px; top:-10000px; width:' + (zoomWinWidth+2) + 'px; height:' + (zoomWinHeight+2) + 'px; z-index:99;">';
		htmlFragment += '<div style="position:relative;border-style:solid;border-width:1px;border-color:' + params.borderColor + ';">';
		htmlFragment += '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="' + 
						zoomWinWidth + '" height="' + zoomWinHeight + '" id="' + elementId + '" align="top" swLiveConnect="true">';
		htmlFragment += '<param name="movie" value="' + externalWinURL + '" />';
		htmlFragment += '<param name="allowScriptAccess" value="always" />';
		htmlFragment += '<param name="bgcolor" value="' + params.bgColor + '" />';
		htmlFragment += '<param name="scale" value="noscale" />';
		htmlFragment += '<param name="base" value="." />';
		htmlFragment += '<param name="flashvars" value="' + flashVars + '" />';
		htmlFragment += '<embed src="' + externalWinURL + '" base="." quality="high" scale="noscale" bgcolor="' + params.bgColor + '" width="' + zoomWinWidth + '" height="' + zoomWinHeight + '" name="' + elementId + '" align="top" allowScriptAccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"';
		htmlFragment +=	' flashvars="' + flashVars + '" >';
		htmlFragment += '</embed></object></div></div>';
		//alert(htmlFragment);
		document.writeln(htmlFragment);
		
		return elementId;
	}
}

/**
 * Embed an HTML personalization UI into the given DIV. If no XML data is found, 
 * the personalization UI will not be displayed. 
 * 
 * @param divId The identifier of the DIV that we will render the personalization UI into.
 *
 * NOTE: This will automatically wire the UI to the *last* embedded interactive display. 
 */
function embedPersonalizationUI( divId )
{
	
	// generate the personalization XML string
	var info = Concept.registry.lastDisplayInfo;
	//alert("info: " + Concept.registry.lastDisplayInfo + " : " + Concept.registry.lastDisplayInfo.customerId);

	var pXML =  info.baseURL + "customers/" + info.customerId + "/" + info.productId + "/" + info.productId + "_" + info.displayId + 
							 "/personalization_" + info.productId + "_" + info.displayId + ".xml";
	
	// create a callback holding a reference to the last Concept preloader Flash embed.
	var callback = new Object();
	
	callback.handler = this;
	callback.embedElementId = info.embedElementId;
	callback.divId = divId;
	callback.onChanged = function( textId )
	{
		this.handler.onPersonalizationChanged( textId, this.embedElementId, this.divId );
	}

	
	Concept.Personalization.generateUI( divId, pXML, callback, callback.onChanged );
}

/**
 * Callback from personalization UI that the personalization information changed.
 * @param textId The identifier of the personalization text that changed. 
 */
function onPersonalizationChanged( textId, embedElementId, divId )
{
	var formState = Concept.Personalization.getFormState( divId );
	var textState;
	for ( var i=0;i<formState.length;i++ )
	{
		textState = formState[i];
		if ( textState.id == textId )
		{
			var val = textState.id + ":::" + textState.text + ":::" + textState.fontId + ":::" + textState.color;
			var embedElement = getFlashMovieObject( embedElementId );
			//alert( "embed: " + embedElement + " : " + embedElementId );
			embedElement.SetVariable( "personalizedTextChanged", val );
		}
	}
}

/**
 * Utility function to select or unselect a Category within Concept.
 * @param categoryGroupId The ID of the CategoryGroup ( VIEW, VARIATION, HOTSPOT, IMAGETYPE )
 * @param inventoryId The inventoryId of the Category.
 */
function selectCategory( categoryGroupId, inventoryId )
{
	executeConceptInternalCommand( buildCommand( categoryGroupId, inventoryId ) );
}

/**
 * Utility function to select or unselect a Category within Concept.
 * @param embedId The id of the embedded swf element
 * @param categoryGroupId The ID of the CategoryGroup ( VIEW, VARIATION, HOTSPOT, IMAGETYPE )
 * @param inventoryId The inventoryId of the Category.
 */
function selectCategoryById( embedId, categoryGroupId, inventoryId )
{
	executeConceptInternalCommand( buildCommand( categoryGroupId, inventoryId ) , embedId );
}

function buildCommand( categoryGroupId, inventoryId )
{
	var command = "";
	if ( inventoryId == null )
	{
		command = "concept://unselect:" + categoryGroupId;
		
		// For hotspots, when we unselect we need to select a MAIN image
		if ( categoryGroupId.toUpperCase() == "HOTSPOT" )
		{
			command += ";select:category:IMAGETYPE:MAIN";
		}
			
	}
	else
	{
		command = "concept://select:category:" + categoryGroupId + ":" + inventoryId;
		if ( categoryGroupId.toUpperCase() == "HOTSPOT" )
		{
			// For hotspots, when we select one we need to make sure to select a ZOOM image.
			command += ";select:category:IMAGETYPE:ZOOM"
		}
	}
	
	return command;
}


/**
 * Execute any command that can be understood by the InternalLinkVariableEvaluator class. The 
 * following is likely the most useful to know in the Javascript context:
 *
 * - concept://select:category:[cg]:[cat]   Select the Category in the [cg] CategoryGroup with the [cat] Category, 
 * 											where [cat] is a Category inventoryId or ID.  [cg is VIEW, VARIATION, HOTSPOT, or IMAGE_TYPE]
 * - concept://unselect:[cg]			    Unselect the selected category in the [cg] CategoryGroup.
 *
 * @param command	a command to execute
 * @param pEmbedId	optional embedId for the swf element
 */
function executeConceptInternalCommand( command, pEmbedId )
{
	//alert( "command: " + command);
	var embedId = ( pEmbedId ) ? pEmbedId : Concept.registry.lastDisplayInfo.embedElementId;
	var embedElement = getFlashMovieObject( /*Concept.registry.lastDisplayInfo.embedElementId*/embedId );
	embedElement.SetVariable( "conceptInternalCommand", command ); 
}


/** invoked on a click in the focused window - bug fix **/
function concept_focusAway() {
        cINPUT = document.getElementsByTagName('INPUT');

        for ( var i=0 ; i<cINPUT.length ; i++ )
        {
                if ( cINPUT[i].textId )
                {
                        cINPUT[i].blur();
                }
        }
}



function showZoomWindow( id )
{
	var div = getDiv( id );
	var pos = Concept.registry.divInfo[ id ];
	
	div.style.left = pos.x + "px";
	div.style.top = pos.y + "px";

	toggleDiv(id, 1);
}

function hideZoomWindow( id )
{
	toggleDiv(id, 0);
}



function toggleDiv(szDivID, iState) // 1 visible, 0 hidden
{
    if(document.layers)	   //NN4+
    {
       document.layers[szDivID].visibility = iState ? "show" : "hide";
    }
    else if(document.getElementById)	  //gecko(NN6) + IE 5+
    {
        var obj = document.getElementById(szDivID);
        obj.style.visibility = iState ? "visible" : "hidden";
        
        if ( ! iState )
        {
          // WORKAROUND for Firefox on OSX. forces rerendering
          obj.style.padding = '10px';
          obj.style.padding = '0px';
        }
        
    }
    else if(document.all)	// IE 4
    {
        document.all[szDivID].style.visibility = iState ? "visible" : "hidden";
    }
}

function getDiv(szDivID)
{
	
    if(document.layers)    //NN4+
    {
       return document.layers[szDivID];
    }
    else if(document.getElementById)      //gecko(NN6) + IE 5+
    {
        return document.getElementById(szDivID);
    }
    else if(document.all)       // IE 4
    {
        return document.all[szDivID];
    }
}

function getFlashMovieObject(movieName)
{
  if (window.document[movieName]) 
  {
      return window.document[movieName];
  }
  if (navigator.appName.indexOf("Microsoft Internet")==-1)
  {
    if (document.embeds && document.embeds[movieName])
      return document.embeds[movieName]; 
  }
  else // if (navigator.appName.indexOf("Microsoft Internet")!=-1)
  {
    return document.getElementById(movieName);
  }
}


function hasFlash()
{
	var plugin = (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"]) ? 	navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin : 0;
	
	if ( plugin )
	{
		var MM_contentVersion = 7;
		var words = navigator.plugins["Shockwave Flash"].description.split(" ");
		for (var i = 0; i < words.length; ++i)
		{
			if (isNaN(parseInt(words[i])))
				continue;
			var MM_PluginVersion = words[i]; 
	    }
		this.MM_FlashCanPlay = MM_PluginVersion >= MM_contentVersion;
	}
	else if (navigator.userAgent && navigator.userAgent.indexOf("MSIE")>=0 
	   && (navigator.appVersion.indexOf("Win") != -1))
	{
		document.write('<SCR' + 'IPT LANGUAGE=VBScript\> \n'); //FS hide this from IE4.5 Mac by splitting the tag
		document.write('on error resume next \n');
		document.write('MM_FlashCanPlay = ( IsObject(CreateObject("ShockwaveFlash.ShockwaveFlash.7")))\n');
		document.write('</SCR' + 'IPT\> \n');
	}	
	return this.MM_FlashCanPlay; 
}
