// ***********************************************
//
// $CVSHeader: presspack_www/js/popup.js,v 1.7 2007/03/13 11:44:21 Dave Exp $
//
// Description: Defines operations for the creation DHTML 'non-blockable' popup content
//
// ***********************************************

// ** Global variables **

// Lightbox page content
var lightBoxPages = new Array ();

// Define a lightbox
var lightbox = null;

// Define lightbox template
var myTemplate = '<div class="bbcjsUiLightBoxDefault">' +
'<span id="bbcjsUiLightBoxClose" title="Return to main window">Close [x]</span>' + 
	'</div>';

// Number of pages in lightbox
var pageNumber = 0;

// *** Page  variables ***

//Default popup size in pixels, if not specified and not dynamically calculated
var default_width = 600;
var default_height = 440;


// Checks browser version; if IE5.5+ or non-IE, use pop-in IFRAMES; if <IE 5.5, use window.open
function popup (URL, this_width, this_height)
{
	
	// Check browser version
  var agt=navigator.userAgent.toLowerCase();
  var is_major = parseInt(navigator.appVersion);
  var is_minor = parseFloat(navigator.appVersion);
	var is_ie     = (agt.indexOf("msie") != -1);
	var is_ie3    = (is_ie && (is_major < 4));
	var is_ie4    = (is_ie && (is_major == 4) && (agt.indexOf("msie 4")!=-1) );
	var is_ie5    = (is_ie && (is_major == 4) && (agt.indexOf("msie 5.0")!=-1) );
  var is_ie5_5up =(is_ie && !is_ie3 && !is_ie4 && !is_ie5);
		
	// Check if dimensions supplied
	var pop_width, pop_height;
	
	if (this_width)
	{ pop_width = this_width;}
	else {pop_width = default_width;}
	
	if (this_height)
	{ pop_height = this_height;}
	else {pop_height = default_height;}		
		
	//If the browse is IE5.5+ or not IE
	if ((is_ie5_5up) || (!is_ie))
	{	popin(URL, pop_width, pop_height) ;}
	else
	{	popWindow(URL, pop_width, pop_height) ;}
		
}// popup()


/*
   Function: popin

   Popup the given URL in an IFRAME using the optional parameters

   Parameters:

      URL - The URL open the content to pop up
      this_width - The width of the popup (optional)
      this_height - The height of the popup (optional)

*/
function popin(URL, this_width, this_height) 
{
	// Create the page content
	var pf = document.createElement('iframe');
	pf.src = URL;
	pf.width = this_width;
	pf.height = this_height;
	var pc = document.createElement('div');
	pc.appendChild(pf);		
	
		// Insert it into a new page
		window.parent.lightBoxPages[pageNumber] = pc;	

	// If there is already pages
	if (window.parent.pageNumber > 0)
	{
		
		// Increase the page number
		var temp = pageNumber;
		pageNumber++;	

		window.parent.lightbox.show(temp);		

	} else {
			
			// Calculate box horizontal position		
			var this_top = calcBoxTop();
		
			// create the JS lightbox
			lightbox = new bbcjs.ui.LightBox( 
					lightBoxPages, {
					showNav: true,
					width: this_width, 
					height: this_height,
					top: this_top,
					left: 140,
					template:myTemplate }); 			
			
			// Open the light box (on 1st page)
			lightbox.open();
			
			// Increase the page number
			pageNumber++;									
	 
	 } // If a lightbox is already open
	 
	 // Offset the close button 
	 $('bbcjsUiLightBoxClose').style.top = '-22px';
	 $('bbcjsUiLightBoxClose').style.right = '-5px';	
	 $('bbcjsUiLightBoxClose').style.width = this_width + 10 + 'px';
	 $('bbcjsUiLightBoxClose').style.textAlign = 'right';
	 $('bbcjsUiLightBoxClose').style.fontSize = '1.3em';
	  
	
} // popup()

function calcBoxTop()
{	
	// Offset from screen top in pixels
	var offset = 50;
	
	return document.body.scrollTop + offset;
}

// Popup new window function; for <IE5.5 that don't support IFRAMES
function popWindow(URL, this_width, this_height)
{
	var x = 10, y = 10; // default position
	
	if (window.screen) {
		var aw = window.screen.availWidth;
		var ah = window.screen.availHeight;
		x = (aw - this_width) / 2;
		y = (ah - this_height) / 2;
	}
	
	// Open in new window
	var pop_window = window.open(URL,'PressPackPopup','width=' + this_width + ',height=' + this_height + ',left=' + x + ',screenX=' + x + ',top=' + y + ',screenY=' + y + ',fullscreen=no,toolbar=yes,location=no,directories=no,status=no,menubar=yes,scrollbars=yes,resizable=yes');
	
	self.name = "main";
		 
} // popWindow()

//******************* Aliased Functions ***********************

function emailsPopwin (URL, this_width, this_height) { popup(URL, this_width, this_height);	} 
function examplePopwin(URL, this_width, this_height) { popup(URL, this_width, this_height);	}
function openWindow   (URL, this_width, this_height) { popup(URL, this_width, this_height);	}
function editorPopwin   (URL, this_width, this_height) { popup(URL, this_width, this_height);	}
function galleryPopwin   (URL, this_width, this_height) { popup(URL, this_width, this_height);	}
function gamePopwin   (URL, this_width, this_height) { popup(URL, this_width, this_height);	}



// Overridden Lightbox Class for use with popups

/*
Title: UI

Overview:
	Provides widget and effects classes
	
Testsite:
	For worked examples see http://pandora.wc.bbc.co.uk/jstools/ui/
*/

bbcjs.trace('<b><font color="green">jst_ui.js</font> was included.</b>', 2);


/*
Namespace: bbcjs.ui
	Namespace for the UI module
*/
bbcjs.ui = {};
//Module constructor was removed in approx sept 2007
//bbcjs.ui.prototype = new bbcjs.Module("ui", 1, "$Revision: 1.7 $", "$Date: 2007/03/13 11:44:21 $");




// #################################################################################################


/*
Class: bbcjs.ui.LightBox
	Class for implementing a lightbox.
	
	This allows you to display content in a centrally positioned, floated div whilst masking out 
	the rest of the page below. 

Constructor:
	> new bbcjs.ui.LightBox( content [,opts] );
	
Arguments:
	content - an array of objects, whose values are inserted into 
	each screen of the lightbox. By default the objects should contain height, width, 
	src and description properties. If you want to display different sorts of object you 
	can supply a custom template as an option
	opts - (optional) an object with some/all of the same properties as an instance of 
	the <bbcjs.ui.LightBoxOptions> class. Note that all properties are optional

Properties:
	id - unique ID for this instance
	content - array of objects to display
	opts - configuration options
	current - position number of the current content object being displayed
	eventId - unique ID for the window resize event listener
	elemeMask - mask div element
	elemOuter - outer lightbox div
	elemInner - inner lightbox div element

See Also:
	* <bbcjs.ui.LightBoxOptions>

Examples:
	Simple lightbox
	(code)
	var lightbox = new bbcjs.ui.LightBox([{
		width: '400', height: '300',
		description: 'Chopper is a dog',
		src: "chopper.jpg"
	}]);
	lightbox.open();
	(end)
	Lightbox with non-standard options
	(code)
	var lightbox = new bbcjs.ui.LightBox([{   
		width: '400', height: '300',
		description: 'Chopper is a dog',  
		src: "chopper.jpg"
	}], {
		maskColor: '#244B84',
		maskOpacity: '90',
		borderWidth: 10,
		borderColor: '#6E8CB8',
		closeBackground: '#6E8CB8'
	});
	lightbox.open();
	(end)
 */
bbcjs.ui.LightBox = function(content, opts)
{
	this.content = content;
	this.opts = Object.extend(new bbcjs.ui.LightBoxOptions(this), opts);
	this.current = null;
	this.eventId = null;
	this.elemMask = bbcjs.dom.createElement( 'span', {id: 'bbcjsUiLightBoxMask'} );
	this.elemOuter = bbcjs.dom.createElement( 'div', {id: 'bbcjsUiLightBoxOuter'} );
	this.elemInner = bbcjs.dom.appendElement( this.elemOuter, 'div', {id: 'bbcjsUiLightBoxInner'} );
	this.id = bbcjs.ui.LightBox.instances.length;
	
	bbcjs.ui.LightBox.instances.push(this);
};


/*
####################################################################################################
# Group: Class Properties
####################################################################################################
*/


/* 
Property: instances
	Array of <bbcjs.ui.LightBox> instances
*/
bbcjs.ui.LightBox.instances = [];


/*
####################################################################################################
# Group: Methods
####################################################################################################
*/


/*
Method: open
	Opens the lightbox, drawing the necessary elements to the page, if the num param is given this 
	content item is opened, otherwise the default is the first item. Returns the lightbox object.

Arguments:
	num - (optional) position of the item in the content array to open 

Returns:
	The lightbox instance

Example:
	> lightbox.open();  // open the first item
	> lightbox.open(2); // open the 3rd item (content array is zero based)
*/
bbcjs.ui.LightBox.prototype.open = function(num)
{
	bbcjs.trace('bbcjs.ui.LightBox.open()');
	
	var item = num || 0;

	document.body.insertBefore(this.elemOuter, document.body.firstChild);
	document.body.insertBefore(this.elemMask, document.body.firstChild);
	this.drawMask();
	this.eventId = bbcjs.dom.addObjectEventListener( window, 'resize', this );
	this.show(item);
	
	return this;
};


/*
Method: close
	Closes the lightbox and remove any lightbox elements from the page

Returns:
	The lightbox instance

Example:
	> lightbox.close();
 */
bbcjs.ui.LightBox.prototype.close = function()
{
	bbcjs.trace('bbcjs.ui.LightBox.close()');
	
	bbcjs.dom.removeEventListener(this.eventId);
	document.body.removeChild(this.elemMask);
	document.body.removeChild(this.elemOuter);
	
	// Set current number of pages to zero
	pageNumber = 0;

	return this;
};


/*
Method: show
	Display a particular item from the content array. The lightbox must be already open.

Arguments:
	num - the content item to show

Returns:
	The lightbox instance

Example:
	> lightbox.show(2);
 */
bbcjs.ui.LightBox.prototype.show = function (num)
{
	bbcjs.trace('bbcjs.ui.LightBox.show()');
	
	this.current = parseInt(num);
	
	this.drawBox();
	this.positionBox();
	this.addBoxHandlers();
	
	return this;
};


/*
Method: next
	Show to the next content item

Returns: 
	The new item position

Example:
	> lightbox.next();
 */
bbcjs.ui.LightBox.prototype.next = function()
{
	this.show(this.current + 1);
	
	return this.current;
};


/*
Method: previous
	Show to the previous content item

Returns: 
	The new item position

Example:
	> lightbox.previous();
*/
bbcjs.ui.LightBox.prototype.previous = function()
{
	this.show(this.current - 1);
	
	return this.current
};


/*
Method: nextExists
	Internal method which checks to see if we are at the end of the content array
*/
bbcjs.ui.LightBox.prototype.nextExists = function ()
{
	return (this.current < (this.content.length -1)) ? true : false;
};


/*
Method: previousExists
	Internal method which checks to see if we are at the start of the content array
 */
bbcjs.ui.LightBox.prototype.previousExists = function ()
{
	return (this.current > 0) ? true : false;
};


/*
Method: handleResize
	Internal method which re-draws the lightbox if the window is resized
*/
bbcjs.ui.LightBox.prototype.handleResize = function (e)
{
	bbcjs.trace('bbcjs.ui.LightBox.handleResize()');
	
	this.drawMask();
	this.positionBox();

	return bbcjs.dom.stopEvent(e);
};

/*
Method: drawMask
	Internal method which sets up the mask div with the correct width, height and opacity
*/
bbcjs.ui.LightBox.prototype.drawMask = function ()
{
	bbcjs.trace('bbcjs.ui.LightBox.drawMask()');
	
	var height, width, opacityName, oapcityValue;
	
	if (document.body.clientHeight)
	{
		height = (document.body.clientHeight > document.body.scrollHeight) ? 
			document.body.clientHeight : document.body.scrollHeight;
	}
	else height = document.body.scrollHeight;

	if (window.innerWidth)
	{
		if (window.innerWidth != document.body.offsetWidth)
		{
			width = document.body.offsetWidth;
        }
		else width = window.innerWidth;
	}
	else
	{
		width = document.body.clientWidth;
	}

	bbcjs.dom.setStyles( this.elemMask, { 
		'height': height,
		'width': width, 
		'backgroundColor': this.opts.maskColor
	});
	
	opacityName = (document.all) ? "filter" : "opacity";
	oapcityValue = (document.all) ? "alpha(opacity="+this.opts.maskOpacity+")" : (this.opts.maskOpacity/100);
    this.elemMask.style[opacityName] = oapcityValue;
    
};



/*
Method: drawBox
	Internal method which inserts content into the templates and resets the styles
*/
bbcjs.ui.LightBox.prototype.drawBox = function()
{
	bbcjs.trace('bbcjs.ui.LightBox.drawBox()');
	
	//OVERRIDE: force content to be append content as HTML (not a string)
	this.elemInner.innerHTML = this.opts.template.supplant(this.content[this.current]) + ((this.content[this.current]).innerHTML);
	
	this.elemInner.style.width = (typeof(this.opts.width) == 'function' ) ?
		this.opts.width(this) : 
		this.opts.width;
	
	bbcjs.dom.setStyles(this.elemOuter, {
		borderColor: this.opts.borderColor,
		borderWidth: this.opts.borderWidth,
		borderStyle: this.opts.borderStyle,
		backgroundColor: this.opts.boxBackground, 
		color: this.opts.boxColor
	});
	
	
	if ($('bbcjsUiLightBoxClose'))
	{
		bbcjs.dom.setStyles($('bbcjsUiLightBoxClose'), {
			color: this.opts.closeColor,
			backgroundColor: this.opts.closeBackground
		});
	}
		
};


/*
Method: positionBox
	Internal method which positions the content box.
	If the user has specified 'top' and 'left' opts then the lightbox is set
	in this position, otherwise it is positioned in the center of the window.
*/
bbcjs.ui.LightBox.prototype.positionBox = function()
{
	bbcjs.trace('bbcjs.ui.LightBox.positionBox()');
	
	if (this.opts.top)
	{
		this.elemOuter.style.top = this.opts.top;
	}
	else if (window.innerHeight)
	{
		this.elemOuter.style.top = (((window.innerHeight - this.elemOuter.offsetHeight)/2) + 
			window.pageYOffset);
	}
	else
	{
		this.elemOuter.style.top = (((document.body.clientHeight - this.elemOuter.offsetHeight)/2) + 
			document.body.scrollTop);
	}
	
	if (this.opts.left)
	{
		this.elemOuter.style.left = this.opts.left;
	}
	else if (window.innerWidth)
	{
		this.elemOuter.style.left = ((window.innerWidth - this.elemOuter.offsetWidth)/2);
	}
	else
	{
		this.elemOuter.style.left = ((document.body.clientWidth - this.elemOuter.offsetWidth)/2);
	}
};


/*
Method: addBoxHandlers
	Internal method which adds the appropriate event listeners to the navigation elements, or hides 
	them if no nav is required
*/
bbcjs.ui.LightBox.prototype.addBoxHandlers = function()
{
	bbcjs.trace('bbcjs.ui.LightBox.addBoxHandlers()');
	
	var nextId = 'bbcjsUiLightBoxNext';
	var prevId = 'bbcjsUiLightBoxPrevious';
	var closeId = 'bbcjsUiLightBoxClose';
	var disabled = 'bbcjsUiLightBoxDisabled';
	var instance = bbcjs.ui.LightBox.instances[this.id];
	
	if ($(closeId))
	{
		bbcjs.dom.addEventListener($(closeId), 'click', instance.close,  instance);
	}
	if (!this.opts.showNav)
	{
		bbcjs.dom.hideElement(nextId, prevId);
		return;
	}
	
	if ($(nextId) && this.nextExists())
	{
		bbcjs.dom.addEventListener($(nextId), 'click', instance.next, instance);
	}
	else if ($(nextId))
	{
		bbcjs.dom.addClassName($(nextId), disabled);
	}
	if ($(prevId) && this.previousExists())
	{
		bbcjs.dom.addEventListener($(prevId), 'click', instance.previous, instance);
	}
	else if ($(prevId))
	{
		bbcjs.dom.addClassName($(prevId), disabled);
	}
};


// #################################################################################################



/*
Class: bbcjs.ui.LightBoxOptions
	Provides the base set of options for a <bbcjs.ui.LightBox> object
	
	Users do not need to create any instances of this class, but may refer to see
	which options they can pass to the <bbcjs.ui.LightBox> constructor.

Properties:
	maskColor - background color of the mask, default is #000
	maskOpacity - opacity of the mask, default is 60
	left - position of lightbox from the left edge of the window, default is null (centred)
	top - position of lightbox from the top edge of the window, default is null (centred)
	borderWidth - border width of the lightbox, default is 5
	borderStyle - border style of the lightbox, default is solid
	borderColor - border color of the lightbox, default is #999
	closeColor - text color of the close button, default is #fff
	closeBackground - background color of the close button, default is #999
	boxBackground - background color of the lightbox, default is #fff
	boxColor - color of the text in the lightbox, default is #000
	showNav - whether navigation links be shown, default is true if there is more than one content item
	template - default is shown below
	width - function to determine the width of the lightbox, can be overridden with a 
		simple number or string
	
Template:
	The default template used to insert content items is shown below, this can be overridden by 
	passing an alternative as 'template' value to the <bbcjs.ui.LightBox> constructor.
	
	You may want to define your onw template if your content differs from the default "height", 
	"width", "src" and "description". Substitution of values is marked using curly braces, using 
	the <String.supplant> method.
	
	(code)
	<div class="bbcjsUiLightBoxDefault">
	<button id="bbcjsUiLightBoxClose" title="Return to main window">Close</button>
	<img src="{src}" width="{width}" height="{height}" alt="{description}" />
	<p>{description}</p>
	<button id="bbcjsUiLightBoxPrevious">&lt;&lt; Back</button>
	<button id="bbcjsUiLightBoxNext">Forward &gt;&gt;</button>
	</div>
	(end)

See Also:
	* <bbcjs.ui.LightBox>
*/
bbcjs.ui.LightBoxOptions = function(lightbox)
{
	/** Background color of the mask @type String */
	this.maskColor = '#000';
	/** Opacity of the mask @type Number */
	this.maskOpacity = 0;
	/** Position of lightbox from the left edge of the page. Default is centred @type Number */
	this.left = null;
	/** Position of lightbox from the top edge of the page. Default is centred @type Number */
	this.top = null;
	/** Border width of the lightbox @type Number */
	this.borderWidth = 5;
	/** Border style of the lightbox @type String */
	this.borderStyle = 'solid';
	/** Border color of the lightbox @type String */
	this.borderColor = '#999';
	/** Text color of the close button @type String */
	this.closeColor = '#fff';
	/** Background color of the close button @type String */
	this.closeBackground = '#999';
	/** Background color of the lightbox @type String */
	this.boxBackground = '#fff';
	/** Color of the text in the lightbox @type String */
	this.boxColor = '#000';
	/** Should navigation links be shown. Default is true if there is more than one content item @type Boolean */
	this.showNav = lightbox.content.length > 1 ? true : false;
	/** Values from the content objects are inserted into this string using curly quotes, e.g. {description}.  @type String*/
	this.template = '<div class="bbcjsUiLightBoxDefault">' +
		'<button id="bbcjsUiLightBoxClose" title="Return to main window">Close</button>' + 
		'<img src="{src}" width="{width}" height="{height}" alt="{description}" />' +
		'<p>{description}</p>' + 
		'<button id="bbcjsUiLightBoxPrevious">&lt;&lt; Back</button>' + 
		'<button id="bbcjsUiLightBoxNext">Forward &gt;&gt;</button>' +
		'</div>';
		
	/** Function to determine the width of the lightbox, can be overridden with a simple number/string */
	this.width = function ()
	{
		var img = arguments[0].elemOuter.getElementsByTagName('img')[0];
		if (img) return img.width;
		return '';
	};
};


//Insert the stylesheet
document.write('<style type="text/css">@import \'/cs/jst/css/1/ui.css\';</style>');

// Load Page Into Parent Window depending if 'popups' or 'popins' are being used

function loadinparent(url, closeSelf){

	// Check browser version
	var agt=navigator.userAgent.toLowerCase();
	var is_major = parseInt(navigator.appVersion);
	var is_minor = parseFloat(navigator.appVersion);
	var is_ie     = (agt.indexOf("msie") != -1);
	var is_ie3    = (is_ie && (is_major < 4));
	var is_ie4    = (is_ie && (is_major == 4) && (agt.indexOf("msie 4")!=-1) );
	var is_ie5    = (is_ie && (is_major == 4) && (agt.indexOf("msie 5.0")!=-1) );
	var is_ie5_5up =(is_ie && !is_ie3 && !is_ie4 && !is_ie5);
	
	
	if ((is_ie5_5up) || (!is_ie))
	{	loadinparentFromPopin(url, closeSelf) ;} //If the browser is IE5.5+, we are using popins
	else
	{	loadinparentFromPopup(url, closeSelf) ;} // Else we are using popups

}


// If >= IE5.5, change the current page URL
function loadinparentFromPopin(url, closeSelf){
	window.parent.location = url;
}		

// If < IE5.5, close the change the parent URL and close if required	
function loadinparentFromPopup(url, closeSelf){
	self.opener.location = url;
	if(closeSelf) window.close();
}	