﻿
/**
*	@property	page
*
*	Defines the global page instance
*/
var page = null;

/**
*	@class AbstractPage
*
*	The AbstractPage is the base class for all pages. All pages will extend this object
*
*	@author			Daniel Ivanovic dan@anti-blanks.co.uk
*/

var AbstractPage = AbstractView.extend(
	{
		/**
		*   init
		*
		*   Constructs the screen
		*
		*	@param	t - type
		*/
		init: function( t )
		{
			this._super( t );
			
			// create the application
			
			// @@ model
			this.core = new Core( (PREFIX != undefined) ? PREFIX : "" );
			
			// @@ controls
			this.generalControl = new GeneralControl( this.core );
			this.activationsControl = new ActivationsControl( this.core );
			this.vendorsControl = new VendorsControl( this.core );
			
			// @@ manager
			this.generalManager = new GeneralManager( this.core );
			
			// add all controls to managers
			
			this.generalManager.addControl( "GeneralControl", this.generalControl );
			this.generalManager.addControl( "ActivationsControl", this.activationsControl );
			this.generalManager.addControl( "VendorsControl", this.vendorsControl );
			
			// setup the page
			this.setup();
		},
		
		/**
		*   setup
		*
		*   Sets up the view instance
		*/
		setup: function()
		{
			//this.debug( "setting up screen " + ErrorEvent_ERROR );
			
			// define the object scope
			
			var obj = this;
			
			// listen to applicable events
			
			$( this.core ).bind( FeedbackEvent_FEEDBACK_RECEIVED, function(evt, data) { obj.update( evt.type, data ); } );
			
			// build the screen
			this.build();
		},
		
		/**
		*   build
		*
		*   Builds the view
		*/
		build: function()
		{
			// build all page elements
			
			// build the dialogues
			
			this.buildDialogues();
			
			// build abstract screen components
			
			this.buildComponents();
			
			// handle any global 'post-build' page functionality
			
			// fix all PNG
			this.fixScreenPNG();
			
			// fix the IE box model
			//$( 'div' ).fixBoxModel().fixDoubleMargin();
			//$( 'ul' ).fixBoxModel().fixDoubleMargin();
			//$( 'li' ).fixBoxModel().fixDoubleMargin();
			//$( 'span' ).fixBoxModel().fixDoubleMargin();
			
			// fix the fonts in IE
			//Cufon.now();
		},
		
		/**
		*   buildDialogues
		*
		*   Builds the page dialogues
		*/
		buildDialogues: function()
		{
			//this.debug( "building page dialogues " );
			
			// create dialogue manager instance
			
			this.dialogueManager = new DialogueManager( this.core );
			
			// build all dialogues and add to manager
			
			// @@ TODO : Add abstract dialogues here
		},
		
		/**
		*   buildComponents
		*
		*   Builds the page components
		*/
		buildComponents: function()
		{
			//this.debug( "building page components " );
			
			var obj = this;
			
			// @@ messages
			this.pageMessages = new PageMessages( this.generalManager, "div#cmp_messages" );
			this.pageMessages.setup();
			
			// load the nifty corners
			this.loadNiftyCorners();
		},
		
		/**
		*   showLoader / hideLoader
		*
		*   Shows / Hides the loader dialogue
		*/
		/*showLoader: function()
		{
			// open the loader dialogue
			this.dialogueManager.openDialogue( "dialog_loader", true );
		},
		
		hideLoader: function()
		{
			// close the loader dialogue
			this.dialogueManager.closeDialogue( "dialog_loader" );
		},*/
		
		/**
		*   fixScreenPNG
		*
		*   Fixes all the screen png's
		*/
		fixScreenPNG: function()
		{
			//DD_belatedPNG.fix( "a.a_sign_up_btn_134x60, .a_sign_up_btn_134x60 span" );
			//DD_belatedPNG.fix( "a.a_buy_credits_btn_134x60, .a_buy_credits_btn_134x60 span" );
		},
		
		/**
		*   loadNiftyCorners
		*
		*   Loads all the page's nifty rounded corners
		*/
		loadNiftyCorners: function()
		{
			//this.debug( "loading corners " );
			
			Nifty("div#nav","bottom, big", this.core.getPrefix());
            Nifty("div#newsfeed","bottom, big", this.core.getPrefix());
            Nifty("div#mailing","bottom, big", this.core.getPrefix());
			Nifty("div#tutorial_video_holder","big", this.core.getPrefix());
			Nifty("li.testimonial", "big", this.core.getPrefix());
			Nifty("div.message_display_good","big", this.core.getPrefix());
			Nifty("div.message_display_bad","big", this.core.getPrefix());
			Nifty("div.message_display_note","big", this.core.getPrefix());
		},
		
		/**
		*   update
		*
		*   Updates the view
		*
		*	@param	t - event type
		*	@param	d - data
		*/
		update: function(t, d)
		{
			//this.debug( "updating " + t + " : " + d );
			
			switch ( t )
			{
				// @@ case : feedback event : feedback received
				case FeedbackEvent_FEEDBACK_RECEIVED:
					
					if ( d.feedbackScope == this )
						this.pageMessages.showMessages( d );
				
					break;
			}
			
			// update all screen components
			
			this.pageMessages.update( t, d );
			
			// update all dialogues
			
			this.dialogueManager.updateDialogues( t, d );
			
			// call to super
			this._super( t, d );
		}
	}
);

/**
*	@class AbstractMessages
*
*	The AbstractMessages is the base display class for all message display classes
*
*	@author			Daniel Ivanovic dan@anti-blanks.co.uk
*/

var AbstractMessages = AbstractView.extend(
	{
		/**
		*   init
		*
		*   Constructs the page messages view
		*
		*	@param	t - object type
		*	@param	m - manager instance
		*	@param	h - view holder instance
		*/
		init: function(t, m, h)
		{
			this._super( t, m, h );
		},
		
		/**
		*   setup
		*
		*   Sets up the view instance
		*/
		setup: function()
		{
			//this.debug( "setting up" );
			
			this.build();
		},
		
		/**
		*   build
		*
		*   Builds the view
		*/
		build: function()
		{
			//this.debug( "building" );
			
			// hide any messages
			this.hideMessages();
			
			// call to super
			this._super();
		},
		
		/**
		*   showMessages
		*
		*   Shows a new list of messages
		*
		*	@param	m - array of message data objects
		*/
		showMessages: function(m)
		{
			//this.debug( "showing messages : " + m.length );
			
			Nifty("div.message_display_good","big", this.manager.core.getPrefix());
			Nifty("div.message_display_bad","big", this.manager.core.getPrefix());
			Nifty("div.message_display_note","big", this.manager.core.getPrefix());
		},
		
		/**
		*   hideMessages
		*
		*   Hides the displayed messages
		*/
		hideMessages: function()
		{
			//this.debug( "hiding message : " + m.messageType );
			
			// clear the messages
			$( this.getHolder() ).html( "" );
			
			// and hide the holder
			$( this.getHolder() ).hide();
		}
	}
);

/**
*	@class PageMessages
*
*	The PageMessages is the display class for all page messages
*
*	@author			Daniel Ivanovic dan@anti-blanks.co.uk
*/

var PageMessages = AbstractMessages.extend(
	{
		/**
		*   init
		*
		*   Constructs the page messages view
		*
		*	@param	m - manager instance
		*	@param	h - view holder instance
		*/
		init: function(m, h)
		{
			this._super( "PageMessages", m, h );
		},
		
		/**
		*   showMessages
		*
		*   Shows a new list of messages
		*
		*	@param	m - messages data object
		*/
		showMessages: function(m)
		{
			//this.debug( "showing messages : " + m.messages.length + " : " + m.messagesType );
			
			// hide any existing messages
			this.hideMessages();
			
			// if there are no messages to show
			// exit the function
			if (  m.messages.length == 0 ) 
				return;
				
			// show the holder
			$( this.getHolder() ).show();
			
			// switch on the message type
			// to define the correct display classes to use
			var msgeTitle = "";
			var msgeId = "";
			var msgeCopyClass = "";
			switch ( m.messagesType )
			{
				// @@ case : message type : good
				case "success":
				
					msgeTitle = "SUCCESS!";
					msgeId = "message_display_good";
					msgeCopyClass = "message_good_copystyle_center";
				
					break;
				// @@ case : message type : bad
				case "error":
				
					msgeTitle = "ERROR!";
					msgeId = "message_display_bad";
					msgeCopyClass = "message_error_copystyle_center";
				
					break;
				// @@ case : message type : note
				case "note":
				
					msgeTitle = "NOTE:";
					msgeId = "message_display_note";
					msgeCopyClass = "message_error_copystyle_center";
				
					break;
			}
			
			// loop through messages and display
			var msgesHTML = "";
			for ( i=0; i< m.messages.length; i++ )
			{
				msgesHTML += m.messages[i].message + "<br></br>";
			}
			
			var msgeHTML = '<div class="message_display '+msgeId+'">'
					+	'<span class="'+msgeCopyClass+'">'
					+	'<h2>'+msgeTitle+'</h2>'
					+	'<p>'
					+	msgesHTML
					+	'</p>'
					+	'</span>'
					+	'</div>';
					
			// add to holder
			$( this.getHolder() ).append( msgeHTML );
			
			// scroll window so user can see message
			window.scroll( 0, 0 );
			
			// call to super
			this._super();
		},
		
		/**
		*   update
		*
		*   Updates the view
		*
		*	@param	t - event type
		*	@param	d - data
		*/
		update: function(t, d)
		{
			//this.debug( "updating : " + t + " : " + d );
			
			switch ( t )
			{
				// @@ show a new message
				case PageMessageEvent_SHOW:
				
					this.showMessages( d );
				
					break;
				// @@ hide an existing message
				case PageMessageEvent_HIDE:
				
					this.hideMessages( d );
				
					break;
			}
			
			// call to super
			this._super( t, d );
		}
	}
);

/**
*	@class DialogueData
*
*	The DialogueData holds all data necessary to esatblish a dialogue object
*
*	@author			Daniel Ivanovic dan@anti-blanks.co.uk
*/

var DialogueData = AbstractObject.extend(
	{
		/**
		*   init
		*
		*   Constructs the data object
		*/
		init: function()
		{
			this._super( "DialogueData" );
			
			this.dialogId = 0;
			this.displayData = null;
			this.solo = false;
			this.contentData = null;
		},
		
		/**
		*   setDialogId / getDialogId
		*
		*   Sets / Returns the dialogue id
		*/
		setDialogId: function(s) { this.dialogId = s; },
		getDialogId: function() { return this.dialogId; },
		
		/**
		*   setDisplayData / getDisplayData
		*
		*   Sets / Returns the dialog display data 
		*/
		setDisplayData: function(s) { this.displayData = s; },
		getDisplayData: function() { return this.displayData; },
		
		/**
		*   setSolo / getSolo
		*
		*   Sets / Returns the solo boolean 
		*/
		setSolo: function(s) { this.solo = s; },
		getSolo: function() { return this.solo; },
		
		/**
		*   setContentData / getContentData
		*
		*   Sets / Returns the content data object 
		*/
		setContentData: function(s) { this.contentData = s; },
		getContentData: function() { return this.contentData; }
	}
);

/**
*	@class DialogueManager
*
*	The DialogueManager manages the display of all page dialogues
*
*	@author			Daniel Ivanovic dan@anti-blanks.co.uk
*/

var DialogueManager = AbstractManager.extend(
	{
		/**
		*   init
		*
		*   Constructs the dialogue
		*
		*	@param	c - model instance
		*/
		init: function(c)
		{
			this._super( "DialogueManager", c );
			
			// define props
			this.dialogues = new Array();
			this.openDialogues = new Array();
		},
		
		/**
		*   addDialogue / getDialogue
		*
		*   Adds / Returns a dialogue to / from the dialogue array
		*
		*	@param	id - dialogue id
		*	@param	d - dialogue object
		*/
		addDialogue: function(id, d)
		{
			//this.debug( "adding dialogue : " + id );
			
			if ( !id || !d ) {
				alert( "WARNING! : Dialogue id and/or object cannot be recognised" );
				return;
			}
			
			this.dialogues[ id ] = d;
			this.dialogues[ id ].setup();
			
			var obj = this;
			
			// assign to open event
			// This will open the dialogue objects when a dialog is opened
			$( "#" + id ).bind( 'dialogopen', function(evt, ui) {
				//alert( "opening dialogue " + id );
				// handle all open functionality
				// open the dialogue object
				obj.dialogues[ id ].openDialogue();
				// add to open array
				obj.openDialogues[ id ] = obj.dialogues[ id ];
			});
			
			// assign to close event
			// we do this just in case the user closes by means of 'x' button,
			// this will keep the manager up to date on open / closed dialogues
			$( "#" + id ).bind( 'dialogclose', function(evt, ui) {
				//alert( "closing dialogue " + id );
				// handle all close functionality
				// close the dialogue object
				obj.dialogues[ id ].closeDialogue();
				// remove from open array
				delete obj.openDialogues[ id ];
			});
		},
		
		getDialogue: function(id)
		{
			//this.debug( "getting dialogue" );
			
			if ( !this.dialogues[ id ] ) {
				alert( "WARNING! : There is no dialogue named " + id );	
				return;
			}
			
			return this.dialogues[ id ];
		},
		
		/**
		*   openDialogue / closeDialogue
		*
		*   Opens / Closes a dialogue
		*
		*	@param	id - dialogue id
		*	@param	s - solo boolean
		*	@param	d - dialogue content data
		*/
		openDialogue: function(id, s, d)
		{
			//this.debug( "opening dialogue " + id + " : " + s + " : " + d );
			
			// if set to display solo
			// then close all the open dialogues
			if ( s != undefined && s )
				this.closeDialogues();
			
			// if content data has been passed
			// then add the data to the dialog
			if ( d != undefined && d )
				this.dialogues[ id ].setContentData( d );
				
			// scroll the window to the top of the page
			window.scroll( 0, 0 );
			
			//this.debug( "?? " + $( "#" + id ).dialog );
			
			// open the dialog panel
			$( "#" + id ).dialog( "open" );
		},
		
		closeDialogue: function(id)
		{
			//this.debug( "closing dialogue " + id );
			
			// close the dialog panel
			$( "#" + id ).dialog( "close" );
		},
		
		/**
		*	closeDialogues
		*
		*	Closes all open dialogues
		*/
		closeDialogues: function()
		{
			//this.debug( "closing dialogues" );
			
			for ( var i in this.openDialogues )
			{
				this.closeDialogue( i );
			}
		},
		
		/**
		*   updateDialogues
		*
		*   Updates all the dialogues
		*
		*	@param	t - event type
		*	@param	d - event data
		*/
		updateDialogues: function(t, d)
		{
			//this.debug( "updating dialogues " + t + "  " + d );
			
			for ( var i in this.dialogues )
			{
				this.dialogues[ i ].update(t, d);
			}
		}
	}
);

/**
*	@class DialogueMessages
*
*	The DialogueMessages class is the display class for all dialogue messages
*
*	@author			Daniel Ivanovic dan@anti-blanks.co.uk
*/

var DialogueMessages = AbstractMessages.extend(
	{
		/**
		*   init
		*
		*   Constructs the page messages view
		*
		*	@param	m - manager instance
		*	@param	h - view holder instance
		*/
		init: function(m, h)
		{
			this._super( "DialogueMessages", m, h );
		},
		
		/**
		*   showMessages
		*
		*   Shows a new list of messages
		*
		*	@param	m - messages data object
		*/
		showMessages: function(m)
		{
			//this.debug( "showing messages : " + m.messages.length + " : " + m.messagesType );
			
			// hide any existing messages
			this.hideMessages();
			
			// if there are no messages to show
			// exit the function
			if (  m.messages.length == 0 ) 
				return;
				
			// show the holder
			$( this.getHolder() ).show();
			
			// switch on the message type
			// to define the correct display classes to use
			var msgeTitle = "";
			var msgeId = "";
			var msgeCopyClass = "";
			switch ( m.messagesType )
			{
				// @@ case : message type : good
				case "success":
				
					msgeTitle = "SUCCESS!";
					msgeId = "message_display_good";
					msgeCopyClass = "message_good_copystyle_center";
				
					break;
				// @@ case : message type : bad
				case "error":
				
					msgeTitle = "ERROR!";
					msgeId = "message_display_bad";
					msgeCopyClass = "message_error_copystyle_center";
				
					break;
				// @@ case : message type : note
				case "note":
				
					msgeTitle = "NOTE:";
					msgeId = "message_display_note";
					msgeCopyClass = "message_error_copystyle_center";
				
					break;
			}
			
			// loop through messages and display
			var msgesHTML = "";
			for ( i=0; i< m.messages.length; i++ )
			{
				msgesHTML += m.messages[i].message + "<br></br>";
			}
			
			var msgeHTML = '<div class="message_display '+msgeId+'">'
					+	'<span class="'+msgeCopyClass+'">'
					+	'<h2>'+msgeTitle+'</h2>'
					+	'<p>'
					+	msgesHTML
					+	'</p>'
					+	'</span>'
					+	'</div>';
					
			// add to holder
			$( this.getHolder() ).append( msgeHTML );
			
			// scroll the window if necessary
			// we only do this if the message is out of sight
			if ( $( window ).scrollTop() > $( this.getHolder() ).parent().offset().top )
				window.scroll( 0, $( this.getHolder() ).parent().offset().top );
			
			// call to super
			this._super();
		},
		
		/**
		*   update
		*
		*   Updates the view
		*
		*	@param	t - event type
		*	@param	d - data
		*/
		update: function(t, d)
		{
			//this.debug( "updating : " + t + " : " + d );
			
			switch ( t )
			{
				// @@ show a new message
				case DialogueMessageEvent_SHOW:
				
					this.showMessages( d.messages );
				
					break;
				// @@ hide an existing message
				case DialogueMessageEvent_HIDE:
				
					this.hideMessages( d.messages );
				
					break;
			}
			
			// call to super
			this._super( t, d );
		}
	}
);

/**
*	@class AbstractDialogue
*
*	The AbstractDialogue class is the base display class for all dialogues
*
*	@author			Daniel Ivanovic dan@anti-blanks.co.uk
*/

var AbstractDialogue = AbstractView.extend(
	{
		/**
		*   init
		*
		*   Constructs the dialogue
		*
		*	@param	t - type string
		*	@param	m - manager instance
		*	@param	h - view holder instance
		*	@param	d - dialogue data object
		*/
		init: function(t, m, h, d)
		{
			this._super( t, m, h );
			
			// @@ define props
			this.STATE_OPEN = "stateOpen";
			this.STATE_CLOSED = "stateClosed";
			this.STATE_DEFAULT = this.STATE_CLOSED;
			
			// @@ private
			this.currentState = this.STATE_DEFAULT;
			this.dialogueData = d;
			this.contentData = d.getContentData();
			this.dialogueBuilt = false;
			this.compLoader = "div#comp_loader";
		},
		
		/**
		*   setup
		*
		*   Sets up the view instance
		*/
		setup: function()
		{
			//this.debug( "setting up dialogue : " + this.dialogueData.getDialogId() );
			
			if ( !this.dialogueData ) {
				alert( "WARNING! : No dialogue data set " + this.getType() );
				return;
			}
			
			$( "#" + this.dialogueData.getDialogId() ).dialog(
				this.dialogueData.getDisplayData()
			);
			
			// build
			this.build();
		},
		
		/**
		*   build
		*
		*   Builds the view
		*/
		build: function()
		{
			//this.debug( "building" );
			
			// build components
			this.buildComponents();
			
			// register as built
			this.dialogueBuilt = true;
		},
		
		/**
		*   buildComponents
		*
		*   Builds the screen components
		*/
		buildComponents: function()
		{
			//this.debug( "building dialogue components" );
			
			var obj = this;
			
			// @@ messages
			this.dialogueMessages = new DialogueMessages( this.getManager(), "div#" + this.dialogueData.getDialogId() + "_comp_dialogue_msges" );
			this.dialogueMessages.setup();
		},
		
		/**
		*   openDialogue / closeDialogue
		*
		*   Opens / Closes the dialogue
		*/
		openDialogue: function()
		{
			//this.debug( "opening" );
			
			// hie any messages
			this.dialogueMessages.hideMessages();
			
			// register the current state
			this.currentState = this.STATE_OPEN;
		},
		
		closeDialogue: function()
		{
			//this.debug( "closing" );
			
			// register the current state
			this.currentState = this.STATE_CLOSED;
		},
		
		/**
		*   showLoader / hideLoader
		*
		*   Shows / Hides the loader dialogue
		*/
		showLoader: function()
		{
			// if no loader established
			if ( !$( this.compLoader ) )
				return;
				
			// show the loader
			$( this.compLoader ).show();
		},
		
		hideLoader: function()
		{
			// if no loader established
			if ( !$( this.compLoader ) )
				return;
				
			// hide the loader
			$( this.compLoader ).hide();
		},
		
		/**
		*   setContentData / getContentData
		*
		*	Sets / Returns the dialogue content data object 
		*/
		setContentData: function(d) { this.contentData = d; },
		getContentData: function() { return this.contentData; },
		
		/**
		*   update
		*
		*   Updates the view
		*
		*	@param	t - event type
		*	@param	d - data
		*/
		update: function(t, d)
		{
			//this.debug( "updating : " + t + " : " + d );
			
			// if the dialogue has not yet been built
			// return before trying to update components
			if ( !this.dialogueBuilt )
				return;
				
			switch ( t )
			{
				// @@ case : feedback event : feedback received
				case FeedbackEvent_FEEDBACK_RECEIVED:
					
					if ( d.feedbackScope == this )
						this.dialogueMessages.showMessages( d );
				
					break;
			}
			
			// update components
			this.dialogueMessages.update( t, d );
		}
	}
);

// @@ TODO : Move these nasty site functions somewhere more useful

/**
*   getMovie
*
*   Locates and returns a movie within the page
*
*	@param	movie - the name of the movie to return
*/
function getMovie(movie) 
{
	if (navigator.appName.indexOf("Microsoft") != -1) 
	{
		return window[movie];
	} else {
		return document[movie];
	}
}

/**
*   openFullScreenVideo
*
*   Opens full screen video
*
*	@param	video - video path
*/
function openFullScreenVideo(video)
{
	window.open ( PREFIX + "pages/ui/fsvideo.php?vid="+ video +"", "fullscreenvideo","width=1000, height=667"); 
	
	return true;
}

/**
*   closeFullScreenVideo
*
*   Closes full screen video
*
*	@param	movie - movie name
*/
function closeFullScreenVideo(movie) 
{
	getMovie(movie).closeFullScreenVideo();
}
