var mok3_g_currentExperiences = new Hashtable();
var mok3_g_mainClass = '';
var mok3_g_playerDebug = false;
////////////////////////////////
// The prototype.js version of getElementsByClassName is insufficient for our purposes
// so I get rid of them here, and then add my own definitions for it

/// deleting document.get... results in an error-- saying that:
/// TypeError: Object doesn't support this action (number: -2146827843)
try	{ delete document.getElementsByClassName; } catch ( o ) {}
delete Element.getElementsByClassName;

Element.getElementsByClassName = function( element, strTagName, classNames )
{
	if ( typeof element == "string" )
		element = $(element);
	return document.getElementsByClassName( element, strTagName, classNames );
}

/// oElm -- the actual element itself
/// strTagName --- tag name
/// oClassNames --- single string or array or strings
document.getElementsByClassName = function(oElm, strTagName, oClassNames)
{
	var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
	var arrReturnElements = new Array();
	var arrRegExpClassNames = new Array();
	if(typeof oClassNames == "object"){
			for(var i=0; i<oClassNames.length; i++){
					arrRegExpClassNames.push(new RegExp("(^|\\s)" + oClassNames[i].replace(/\-/g, "\\-") + "(\\s|$)"));
			}
	}
	else{
			arrRegExpClassNames.push(new RegExp("(^|\\s)" + oClassNames.replace(/\-/g, "\\-") + "(\\s|$)"));
	}
	var oElement;
	var bMatchesAll;
	for(var j=0; j<arrElements.length; j++){
			oElement = arrElements[j];
			bMatchesAll = true;
			for(var k=0; k<arrRegExpClassNames.length; k++){
					if(!arrRegExpClassNames[k].test(oElement.className)){
							bMatchesAll = false;
							break;                      
					}
			}
			if(bMatchesAll){
					arrReturnElements.push(oElement);
			}
	}
	return arrReturnElements;
}

//////////////////////////////////// TAB MANAGEMENT
var PlayerState = { STOPPED: 0, PAUSED: 1, PLAYING: 2, WAITING: 3 };

function TabState()
{
	this.expCount = 0;
	this.expNames = [];
	this.expPaths = [];
	this.expIds = [];
	this.expThumbPaths = [];
	this.currExp = 0;
	this.viewerContainerClass = 'waiting';
	this.currState = PlayerState.WAITING;
}
Object.extend( TabState.prototype, {
	getCurrState: function()
	{ return this.currState; },
	setCurrState: function( state )
	{
		this.currState = state;
		this._updateViewerContainerClass();
	}
} );

function mok3_addTabState( tabName )
{
	var tabState = new TabState();
	mok3_g_currentExperiences.put( tabName, tabState );
	return tabState;
}

function mok3_getCurrentTab() { return $( 'tabbed_info' ).className; }

function mok3_switchTabs( tabName )
{
	if ( mok3_g_playerDebug )
		alert( mok3_functionToString( mok3_switchTabs ));
		
	var newTab = 'tab_' + tabName;

	// restore player to that tab's state
	var oldTabState = mok3_g_currentExperiences.get( mok3_getCurrentTab() );
	var tabState = mok3_g_currentExperiences.get( newTab );

	// stopping the player ahead of time to deal with the case where the intro movie is being played
	// in the current tab, and we need to interrupt it
	if (mok3_getBroker() != null && mok3_g_brokerHandshake )
		mok3_getBroker().js_interruptExp();

	// update the tab first, because the state change is based on the current tab.
	Element.classNames( 'tabbed_info' ).set( newTab );

	if ( tabState.expCount > 0 )
	{
		switch ( tabState.getCurrState())
		{
		case PlayerState.PLAYING:
			mok3_playerPlayExperience( _mok3_createExpClass( 'exp', tabState.currExp ), tabState.expNames[ tabState.currExp ],
				tabState.expPaths[ tabState.currExp ], tabState.expIds[ tabState.currExp ], tabState.viewerContainerClass );
			break;
		case PlayerState.WAITING:
			mok3_updateNowPlaying( '', '' );
			mok3_refreshViewerContainer( tabState.viewerContainerClass );
			Element.update( 'waiting_click', 'Click to Play' );
			Element.update( 'waiting_name', tabState.expNames[ tabState.currExp ] );
			var sAction = 'javascript:mok3_playManualExperience(' + tabState.currExp + ');';
			Element.update( 'waiting_thumb',
				'<a href="' + sAction + '" style="position: relative; text-align:center;"><span class="thumb">' +
				'<img src="' + tabState.expThumbPaths[ tabState.currExp ] + '" ' +
				' alt="' + tabState.expNames[ tabState.currExp ] + '" class="thumb" />' +
			//	'<img src="images/play65.png" alt="Play" class="play" />' +
				'</span></a>' );
			break;
		default:
			mok3_playerLoadExperience( _mok3_createExpClass( 'exp', tabState.currExp ), tabState.expNames[ tabState.currExp ],
				tabState.expPaths[ tabState.currExp ], tabState.expIds[ tabState.currExp ],
				tabState.getCurrState() == PlayerState.PAUSED, tabState.viewerContainerClass );
			break;
		}
	}
	else
	{
		mok3_refreshViewerContainer( tabState.viewerContainerClass );
	}
	
	if ( typeof _mok3_switchTabs != 'undefined' )
		_mok3_switchTabs( tabName );

	if ( mok3_g_playerDebug )
		Element.update( 'debug', mok3_dumpObject( mok3_g_currentExperiences ));
}

/////////////////////////// PLAYING EXPERIENCES
function mok3_playNext()
{
	var currentTab = mok3_getCurrentTab();
	var tabState = mok3_g_currentExperiences.get( currentTab );
	if ( tabState.currExp < tabState.expCount - 1 )
	{
		++tabState.currExp;
		mok3_playerPlayExperience( _mok3_createExpClass( 'exp', tabState.currExp ), tabState.expNames[ tabState.currExp ],
			tabState.expPaths[ tabState.currExp ], tabState.expIds[ tabState.currExp ], tabState.viewerContainerClass );
	}
	else
	{
		// stopping the player ahead of time to deal with the case where the intro movie is being played
		// in the current tab, and we need to interrupt it
		if (mok3_getBroker() != null)
			mok3_getBroker().js_manualMode();

		tabState.setCurrState( PlayerState.STOPPED );
		//mok3_playerLoadExperience( _mok3_createExpClass( 'exp', tabState.currExp ), tabState.expNames[ tabState.currExp ],
		//	tabState.expPaths[ tabState.currExp ], tabState.expIds[ tabState.currExp ],
		//	tabState.currState == PlayerState.PAUSED, tabState.viewerContainerClass );
	}
	if ( mok3_g_playerDebug )
		Element.update( 'debug', mok3_dumpObject( mok3_g_currentExperiences ));
}

///// user wants to play a specific experience -- mimics pressing play button
function mok3_playManualExperience( index )
{
	if ( mok3_g_playerDebug )
		alert( mok3_functionToString( mok3_playManualExperience ) );
	
	// not a manual stop.
	mok3_g_manualStop = false;
	
  mok3_stats("evt_play_experience");
	var currentTab = mok3_getCurrentTab();
	// set in hashtable for global access
	var tabState = mok3_g_currentExperiences.get( currentTab );
	tabState.currExp = index;
	// stopping the player ahead of time to deal with the case where the intro movie is being played
	// in the current tab, and we need to interrupt it
	if (mok3_getBroker() != null)
		mok3_getBroker().js_interruptExp();
	tabState.setCurrState( PlayerState.PLAYING );
	mok3_playerPlayExperience( _mok3_createExpClass( 'exp', tabState.currExp ), tabState.expNames[ tabState.currExp ],
		tabState.expPaths[ tabState.currExp ], tabState.expIds[ tabState.currExp ], tabState.viewerContainerClass );
	if ( mok3_g_playerDebug )
		Element.update( 'debug', mok3_dumpObject( mok3_g_currentExperiences ));
}

///////// PLAYER CONTROLS

/// expClass -- class of experience being played; if stopping, pass in "" or null
/// expEltId -- id of item in experience list; optional.
function mok3_playerPlayExperience( expEltId, expPrettyName, expPath, expId, viewerClass )
{
	if ( mok3_g_playerDebug )
		alert( mok3_functionToString( mok3_playerPlayExperience ) );

	// visual update
	mok3_updateNowPlaying( expPrettyName, expEltId );
	if ( typeof mok3_updateExperienceList != "undefined" )
		mok3_updateExperienceList( expEltId );

	// scroll whole page, if necessary
	var currentScroll = mok3_getCurrentPageScroll();
	if ( currentScroll.y > $( 'viewer_container' ).offsetTop )
		window.scrollTo( currentScroll.x, $( 'main' ).offsetTop );
	mok3_refreshViewerContainer( viewerClass );

	mok3_playExperience( expPath, expId );
}
function mok3_playerLoadExperience( expEltId, expPrettyName, expPath, expId, pause, viewerClass )
{
	// visual update
	if ( pause )
		mok3_updateNowPlaying( expPrettyName, expEltId );
	else
		mok3_updateNowPlaying( '', '' );
	if ( typeof mok3_updateExperienceList != "undefined" )
		mok3_updateExperienceList( expEltId );

	// scroll whole page, if necessary
	var currentScroll = mok3_getCurrentPageScroll();
	if ( currentScroll.y > $( 'viewer_container' ).offsetTop )
		window.scrollTo( currentScroll.x, $( 'main' ).offsetTop );
	mok3_refreshViewerContainer( viewerClass );
	
	mok3_loadExperience( expPath, expId, pause );
}
function mok3_refreshViewerContainer( vcc )
{
	if ( Element.classNames( 'viewer_container' ) != vcc )
	{
		Element.classNames( 'viewer_container' ).set( vcc );
	}
}

/////////////////////////// VISUAL CHANGES


/// If no arguments are supplied, uses the current experience being played
function mok3_updateNowPlaying( prettyName, expClass )
{
	var mainClass = mok3_g_mainClass;
	if ( expClass != null && expClass != "" )
		mainClass += ' ' + expClass;
	
	mok3_setIdClass( 'main', mainClass );
	mok3_replaceIdContents( 'current_experience', ( prettyName != null && prettyName != "" ? prettyName : '&nbsp;' ) );
}

/////////////////////////// CALLS MADE FROM THE VIEWER

function mok3_viewerStopped()
{
//	alert( 'mok3_viewerStopped' );
  mok3_stats("evt_viewer_stopped");
	// we keep the index of the just-played experience so that they can play it again-- but
	// we need to show it as not being played since the user stopped the experience
	mok3_updateNowPlaying( '', '' );
	mok3_g_currentExperiences.get( mok3_getCurrentTab()).setCurrState( PlayerState.STOPPED );
}

function mok3_viewerPaused()
{
//	alert( 'mok3_viewerPaused' );
  mok3_stats("evt_viewer_paused");
	mok3_g_currentExperiences.get( mok3_getCurrentTab()).setCurrState( PlayerState.PAUSED );
}

// player resumed, not 'played', so to speak
function mok3_viewerPlayed()
{
//	alert( 'mok3_viewerPlayed' );
  mok3_stats("evt_viewer_played");
	
	var tabState = mok3_g_currentExperiences.get( mok3_getCurrentTab());
	mok3_updateNowPlaying( tabState.expNames[ tabState.currExp ], _mok3_createExpClass( 'exp', tabState.currExp ));
	tabState.setCurrState( PlayerState.PLAYING );
}
