/*!
**********************************************************************
@file wizardPages.js

Copyright 2003-2006 Adobe Systems Incorporated.                     
All Rights Reserved.                                                
                                                                    
NOTICE: All information contained herein is the property of Adobe   
Systems Incorporated.                                                                                                                    

***********************************************************************
*/

/**
WizardPage constructor.
The constructor does NOT automatically load the page.  See the LoadRequest() method.
@param		inPageName		Base name of the page, matching the filesystem name.
*/
function WizardPage(inPageName)
{
	/** This unique wizard page name */
	this.pageName = inPageName;
	/** Localization object */
	this.localization = null;
	/** The contents of the BODY tag in the imported documentRoot.  Valid iff document can be successfully loaded */
	this.importedBodyFragment = null;
	/** The WizdardControl owning this page instance */
	this.wizardControl = null;
	/** The alert.html template stream */
	this.alertTemplate = null;
	/** The alert.xml resource map */
	this.alertResourceMap = null;
}


WizardPage.prototype.SetController = function(inController)
{
	this.wizardControl = inController;
}


/**
Return a localized string representing the user interface name
for this workflow step.  This will be displayed along the left
edge of the user interface.
*/
WizardPage.prototype.GetDisplayName = function()
{
	return "Wizard Page";
}


/**
Initiate the loading of the wizard.
*/
WizardPage.prototype.LoadResources = function()
{
	var htmlPath = _concatPaths([this.wizardControl.session.GetResourcesPath(), 'pages/' + this.pageName + '/' + this.pageName + '.html'],
 		this.wizardControl.session.properties["platform"]);
	var htmlResource = this.wizardControl.session.LoadFile(htmlPath);
	if (htmlResource && htmlResource.data)
	{
		/*
		Transit the wizard page HTML into a node owned by the Ahmbed container
		document.  Then we can manage its visibility by simply calling appending
		and removing it.		
		*/
		this.wizardControl.session.LogDebug("HTML data complete: " + this.pageName);
		this.importedBodyFragment = document.createElement("div");
		this.importedBodyFragment.innerHTML = htmlResource.data;

		/*
		Load the localization data and localize the page DOM.
		*/
		var xmlPath = _concatPaths([this.wizardControl.session.GetResourcesPath(), 'pages/' + this.pageName + '/' + this.pageName + '.xml'],
	 		this.wizardControl.session.properties["platform"]);
		this.localization = new Localization(this.wizardControl.session, xmlPath, this.wizardControl.session.properties, false);
		if (this.localization)
			this.localization.LocalizeDOM(this.importedBodyFragment);
		else
			this.wizardControl.session.LogError("Localizing wizard page failed: " + this.pageName);

		/*
		Make a WizardError if there is an error box in the UI.
		*/
		var errorElement = this.getElementById("error");
		if (errorElement)
		{
			this.errorbox = new WizardError(errorElement, this.getElementById("content"), this.wizardControl.textColor);
			//this.errorbox.SetTitle(this.wizardControl.session.localization.GetString("locProblemsEncountered"));
		}

		/*
		Call the page method to let it know the UI is available.
		*/
		this.onResourcesLoaded(); 
	}
	else
	{
		this.wizardControl.session.LogError("Error loading HTML data for: " + this.pageName);
	}
}


/**
Return true if the wizard page wants to be included in the
workflow.  If this method returns false, the WizardControl
will have no further interaction with this object.

A page loaded is not necessairly valid.  See isValid() method.
*/
WizardPage.prototype.isActive = function()
{
	return true;
}


/**
Return the root node of the wizard page DOM.

The DOM may or may not be attached in the node hieararchy.
*/
WizardPage.prototype.GetUIDOM = function()
{
	return this.importedBodyFragment;
}


/**
Default getProperties delegate implementation

Pack up input, select and textarea element values as a property map.
Elements must have a name attribute to be included.
*/
WizardPage.prototype.getProperties = function()
{
	var DOM = this.GetUIDOM();
	if (!DOM)
	{
		alert("WizardPage.getProperties(): Can't find the DOM!");
		return null;
	}
	
	pmap = new Object();
	fields = [ "input", "select", "textarea" ];
	for (var fi = 0; fi < fields.length; fi++)
	{
		var nodes = DOM.getElementsByTagName(fields[fi]);
		for (var ni = 0; ni < nodes.length; ni++)
		{
			var node = nodes[ni];
			if (node.name)
			{
				switch (node.type)
				{
					case "radio":
						if (node.value && node.checked)
							pmap[node.name] = node.value;
						break;
					case "checkbox":
						if (node.checked)
							pmap[node.name] = node.value;
						break;
					case "button":
						break;
					default:
						if (node.value)
							pmap[node.name] = node.value;
				}
			}
		}
	}
	return pmap;
}


/**
Get an element based on id.

document.getElementId() doesn't work when the page isn't attached
into the document tree.  This does the same sort of thing, but just
returns the first element that has a matching id attribute.
*/
WizardPage.prototype.getElementById = function(inId)
{
	var idMatch = function(node, idmatch)
	{
		if (node)
		{
			if (1 == node.nodeType && node.id && idmatch == node.id)
			{
				return node;
			}
			else
			{
				for (var n = 0; n < node.childNodes.length; n++)
				{
					var cn = idMatch(node.childNodes[n], idmatch);
					if (cn)
						return cn;
				}
			}
		}
		return null;
	};

	return idMatch(this.GetUIDOM(), inId);

}


/**
Page defined handler for when the page resources are loaded.
The HTML and XML UI resources are not available before this
method is called.
*/
WizardPage.prototype.onResourcesLoaded = function()
{
	return true;
}


/**
Page defined onSwitchTo handler.

If a page wants to opt out of the workflow for any reason, it
should define an onSwitchTo handler that returns true under
the conditions the page should be shown and false
under the conditions the page should be skipped.

By default this simply calls the isActive() method.  Override
if the participation cannot be determined at load time.
*/
WizardPage.prototype.onSwitchTo = function()
{
	return this.isActive();
}


/**
Page defined onNext handler.

If a page wants to block the switch to the next page, it should define
an onNext handler that returns false under the conditions that the
switch should be blocked.
*/
WizardPage.prototype.onNext = function()
{
	return true;
}


/**
Page defined onBack handler.

If a page wants to block the switch to the previous page, it should define
an onBack handler that returns false under the conditions that the
switch should be blocked.
*/
WizardPage.prototype.onBack = function()
{
	return true;
}


/**
Page defined onShow handler.

If a page wants to invoke code as soon as the page is shown to the user,
override this method.
*/
WizardPage.prototype.onShow = function()
{
	this.setWindowTitle();
	this.wizardControl.session.UISetCloseBoxEnabled(1);
	
	this.wizardControl.focusItem = null;
	
	this.wizardControl.nextButton.SetTabIndex(103);
	this.wizardControl.nextButton.SetAccessKey("n");
	
	this.wizardControl.backButton.SetTabIndex(102);
	this.wizardControl.backButton.SetAccessKey("b");	
	
	return true;
}

/**
Set the window title based on this page's title
*/
WizardPage.prototype.setWindowTitle = function()
{
	this.wizardControl.session.UISetWindowTitle(this.wizardControl.session.localization.GetString("locProductNameInstall", "[productName] Installer: [pageTitle]", { pageTitle: this.GetDisplayName()}));
}


/**
Page defined onSetupModeChanged handler.

If a page wants to invoke code when the setup mode has changed, it should
override this method.
*/
WizardPage.prototype.onSetupModeChanged = function(inOldMode, inNewMode)
{
	return;
}

/**
Method to return the alert.html template file.  

Returns the cached instance if one exists.  Otherwise attempts
to load and return the alert.html template file
*/
/* Obsolete by WizardAlert class, see WizardWidgets.js
WizardPage.prototype.GetAlertTemplate = function()
{
	if (!this.alertTemplate)
	{
		var alertPathArray = new Array(this.wizardControl.session.GetResourcesPath(), "/pages/alert/alert.html");
		var alertPath = _concatPaths(alertPathArray, this.wizardControl.session.defaultProperties.platform);
		
		var alertContents = this.wizardControl.session.LoadFile(alertPath);
		this.alertTemplate = alertContents.data;
		
		// Update the InstallSource URI
		// TODO enable once separate CSS classes are available for the alerts

		var cssURIArray =  new Array(this.wizardControl.session.GetResourcesPath(), "/media/css/alert.css");
		var cssURI = _concatPaths(cssURIArray, this.wizardControl.session.defaultProperties.platform);
		cssURI = "file://" + cssURI;
		// Add branch to pick up different CSS based on os, fonts, etc.
		this.alertTemplate = this.alertTemplate.replace("<CSSPath>", cssURI);
		
		// Load the resource map
		var alertResourcesPathArray = new Array(this.wizardControl.session.GetResourcesPath(), "/pages/alert/alert.xml");
		var alertResourcesPath = _concatPaths(alertResourcesPathArray, this.wizardControl.session.defaultProperties.platform);
		
		var resourceMap = this.wizardControl.session.LoadFile(alertResourcesPath);
		if (resourceMap.data)
		{
			this.alertResourceMap = resourceMap;
		}
	}
	if (!this.alertTemplate ||
		this.alertTemplate.length <= 0)
	{
		throw "Unable to load alert.html";
	}

	return this.alertTemplate;
}
*/

/**
Page defined onCancel handler.

If a page wants to block or otherwise hook into action when
a user clicks the Quit/Cancel button, override this method.
Return false to block exiting the installer.
*/
WizardPage.prototype.onCancel = function()
{
	// Setup the HTML body text for the alert...
	var alertObject = null;
	var resultDialog = null;
	var doCancel = false;
	
	try
	{
		var alertObj = new WizardAlert(this.wizardControl.session);
		alertObj.SetTitle(this.wizardControl.session.localization.GetString("locAlertCancelTitle", "Cancel Installation"));
		if (this.wizardControl.setupMode == kInstallerModeRemove)
			alertObj.SetBody(this.wizardControl.session.localization.GetString("locAlertCancelBodyUninstall"));
		else
			alertObj.SetBody(this.wizardControl.session.localization.GetString("locAlertCancelBody", "<p>Are you sure you want to quit the installer?  You can start the installer again by running Setup.  This will restart the installation process from the very beginning.</p> <p>Click Resume to continue installing.</p>"));

		alertObj.AddButton(this.wizardControl.session.localization.GetString("locAlertCancelResume", "Resume"), "2", { accessKey: "r" } );
		alertObj.AddButton(this.wizardControl.session.localization.GetString("locAlertCancelQuit", "Quit"), "1", { accessKey: "q" } );

		resultDialog = alertObj.Run();
		doCancel = (resultDialog.returnValue == "1");
	}
	catch (ex)
	{
	}
	finally
	{
		alertObject = null;
		resultDialog = null;
	}
	return doCancel;
}

