//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
// 
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------

// This temporary function helps to resolve Javascript errors in the migrated RUP
// content pages. It will be removed once the corresponding .js files are being
// migrated along with the HTML content pages.
function ReferenceHelpTopic (topicName, book , fileName) {
   //document.write("<i>"+ topicName + "<\/i>");
};


var contentPage = {

	backPath: null,
	imgPath: null,
	defaultQueryStr: null,
	queryStr: null,
	isProcessPage: false,
	nodeInfo: null,
	
	// define resource file
	res : new ContentPageResource(),
	
	// define activity layout, need to create this as a place holder 
	// so that the dynamically generated data can be loaded
	processPage: ( typeof ProcessElementPage == "undefined" ) ? null : new ProcessElementPage(),
	
	// define section
	section: new ContentPageSection(),
	
	// define sub-section
	subSection: null,
	
	
	// call this method before the page is loaded
	// this is used to initialize some parameters before the page content is processed
	// for example, if the content needs to use some parameters inside the content
	// this approach is not recommented but keep here for backward compatibility
	preload: function(imgPath, backPath, nodeInfo, defaultQueryStr, hasSubSection, isProcessPage, hasTree) {
		this.isProcessPage = isProcessPage || hasTree;
		this.imgPath = imgPath;
		this.backPath = backPath;
		this.nodeInfo = nodeInfo;
		this.defaultQueryStr = defaultQueryStr;
		this.queryStr = location.search;
		if ( this.queryStr == null || this.queryStr == "" )
		{
			this.queryStr = this.defaultQueryStr;
		}
		
		this.section.init(this.imgPath);
		
		if ( hasSubSection ) {
			this.subSection = new ContentPageSubSection();
		}
		
		if ( this.processPage && (isProcessPage || hasTree) ) {
			this.processPage.init(hasTree);
		}
	},
	
	// call this method when page is loaded
	onload: function() {
		this.section.createSectionLinks('div', 'sectionHeading', this.imgPath);
		if ( this.subSection != null ) {
			this.subSection.createStepLinks('div', 'stepHeading');
		}
		
		if ( this.processPage ) {
			this.processPage.onload();
		} else {
			this.buildBreadcrumns(location.href);
		} 
		
		// user can add customization code here
		// this method will be called when the page is loaded
		// this is equivalent to inserting javascript immediately before the </html> tag
		
	},
	
	// utility methods
	getUrlParameters: function(queryStr)
	{
		var arr = new Array();	
		var pairs = queryStr.split("&");
	   	for (var i = 0; i < pairs.length; i++) {
	     		var pos = pairs[i].indexOf('=');
	     		if (pos == -1) continue;
	     		var argname = pairs[i].substring(0,pos);
	     		var value = pairs[i].substring(pos+1);    	
	     		arr[argname] = value;
		}
		
		return arr;
	},

	getApp : function() {

		if( typeof theApp != "undefined") {
			return theApp;
		} else if ( window.parent && typeof window.parent.theApp != "undefined") {
			return window.parent.theApp;
		}
	
		return null;
	},
	
	getViewFrame: function() {
	
		var app = this.getApp();
		if ( app != null ) {
			return app.nav;
		}
				
		var viewFrame = null;
		for ( var i = 0; i < window.parent.frames.length; i++ ) {
			if ( window.parent.frames[i].name == 'ory_toc_frame' ) {
				var tocFrame = window.parent.frames[i];
				//alert(tocFrame);
				if (tocFrame.frames.length > 0 ) {
					for ( var x = 0; x < tocFrame.frames.length; x++ ) {
						if (tocFrame.frames[x].name == 'ory_toc' ) {
							viewFrame = tocFrame.frames[x];
							break;
						}
					}
				}
			}
		}
	
		return viewFrame;
	},

	buildBreadcrumns: function(url) {
		var viewFrame = this.getViewFrame();
		if ( viewFrame == null ) {
			return;
		}

		var div = document.getElementById("breadcrumbs");
		if (div != null && viewFrame != null && viewFrame.getBreadcrumbs ) {
			if ( this.getApp() == null ) {
				// don't break old code
				var bcs = viewFrame.getBreadcrumbs(url);
				if ( bcs != null && bcs.length > 0 ) {
					this.showBreadcrumns(div, bcs);
				}
			} else {
				var self = this;
				var callback = function(bcs) {
					if ( bcs != null && bcs.length > 0 ) {
						self.showBreadcrumns(div, bcs);
					}
				};
					
				if (contentPage.nodeInfo != null && contentPage.nodeInfo.length > 0 ) {
					viewFrame.getBreadcrumbsByPath(contentPage.nodeInfo, null, callback);
				} else {
					// do nothing
					//viewFrame.getBreadcrumbs(url, callback);
				}
				
			}
			
		}
	
	},


	showBreadcrumns: function(div, /*array*/bcs) {
		if (div == null || bcs == null || bcs.length == 0  ) {
			return;
		}
		
		var html = "";
		for (var i = 0; i < bcs.length; i++ ) {
			var bc = bcs[i]; // {url:url, title:title}
			if ( i > 0 ) {
				html += "&nbsp;>&nbsp;";
			}

			// escape the quotes
			var url = bc.url;
			url = url.replace(/'/g, "\\'");
			url = url.replace(/\"/g, "\\\"");

			html += "<a href=\"" + url + "\">" + bc.title + "</a>" ;
		}

		var html = "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">" 
			+ "<tr><td align=\"left\">" + html + "</td><tr>"
			+ "</table>";
		div.innerHTML = html;
	},
	
	
	resolveUrl: function(url) {
	
		if( typeof theApp == "undefined") {
			return url;
		} else {
			return theApp.resolveContentUrl(url);
		}
	},
	
	/* get the page guid, it's the guid of the element or page*/
	getPageId : function() {
		var e = document.getElementById("page-guid");
		if ( e != null ) {
			return e.getAttribute("value");
		}
		
		return null;
	}
	// helper methods

};
