/// <reference path="../../../../jQuery/1.3.2/jquery-1.3.2-vsdoc.js" />

// ********************************************************************
// 
// Manheim Retail Marketing
// ********************************************************************
// Copyright © 2010 Manheim Retail Marketing.
//
//  Summary
// ******************************
// $Workfile: MultiStateDisplay.js $
// Notes:
//
// File History Information
// ************************
// Created on:					    
// Last Modified:					$Modtime: 18/10/10 10:06 $
// Original Author:					Liam Prescott
// Last Modified by:				$Author: Prescottl $
// Last JS Lint:					
//
// Source Control Information
// **************************
// File Version:					$Revision: 1 $
// VSS Location:					$Archive: /Manheim.Portfolio/Manheim.Portfolio.Web.UI.Client.Assets/assets/js/mrm/lib/display/1.1/MultiStateDisplay.js $
//
// ********************************************************************

// Check / create namespace
if (!mrm.global.isNamespaceDefined("mrm.lib.display"))
{
	mrm.global.createNamespace("mrm.lib.display", "1.1");
}


// Class definition
mrm.lib.display.MultiStateDisplay = mrm.lib.core.BaseClass.subClass
({
		
	/*
	=============================
	CONSTANTS
	=============================
	*/

	/* JQuery element targeting strings */
	"SE_MSD" : ".mrm-msd",
	"SE_MSD_MENU" : ".mrm-msd-menu",
	"SE_MSD_LINK" : ".mrm-msd-dl",
	"SE_MSD_DISPLAY" : ".mrm-msd-d",
	
	"SE_MSD_LINK_PREV" : ".mrm-msd-dl-prev",
	"SE_MSD_LINK_NEXT" : ".mrm-msd-dl-next",
	"SE_MSD_LINK_PAUSE" : ".mrm-msd-dl-pause",
	"SE_MSD_LINK_PLAY" : ".mrm-msd-dl-play",
	"SE_MSD_IMAGE_COUNT" : ".mrm-msd-ic",
	
	
	/* JQuery element targeting string fragments */
	"SF_MSD_DISPLAY" : ".mrm-msd-d-",
	

	/* Class names */
	"CL_LINK_DISABLED" : "mrm-msd-dl-disabled",
	"CL_LINK_NEXT_DISABLED" : "mrm-msd-dl-next-disabled",
	"CL_LINK_PREV_DISABLED" : "mrm-msd-dl-prev-disabled",
	"CL_STATE_PAUSED" : "mrm-msd-paused",

	/* Class name fragments */
	"CF_MSD_STATE" : "mrm-msd-d-",
	
		
	/* Data object properties */
	"DOP_JQ_TARGET" : "jqTarget",
	"DOP_STR_TARGET" : "strTarget",
	
	"DOP_TOTAL_STATES" : "totalStates",
	"DOP_CURRENT_STATE" : "currentState",

	"DOP_UPDATE_IN_PROGRESS" : "updateInProgress",
	"DOP_QUEUE_CHANGE_REQUESTS" : "queueChangeRequests",
	"DOP_QUEUED_STATE_CHANGE" : "queuedStateChange",
	"DOP_QUEUED_STATE_ID" : "queuedStateId",
	
	"DOP_AUTOPLAY" : "autoplay",
	"DOP_AUTOPLAY_DURATION_DEFAULT" : "autoplayDurationDefault",
	"DOP_AUTOPLAY_DURATION_USER_INTERUPTION" : "autoplayDurationUserInteruption",
	"DOP_AUTOPLAY_FOLLOW_USER_CYCLE" : "autoplayFollowUserCycle",
	"DOP_AUTOPLAY_FORWARD_DEFAULT" : "autoplayForwardDefault",
	"DOP_AUTOPLAY_FORWARD" : "autoplayForward",
	"DOP_AUTOPLAY_INSTANCE" : "autoplayInstance",
	"DOP_AUTOPLAY_FOLLOW_USER_CYCLE" : "autoplayFollowUserCycle",

	"DOP_IMAGE_COUNT_SEPARATOR" : "imageCountSeparator",
	"DOP_LOOP" : "loop",
	

	/* Event types */
	"EV_CLICK_CYCLE" : "click.mrm-msd-cycle",
	"EV_CLICK_PLAYCONTROL" : "click.mrm-msd-playControl",
	"EV_CORE_STATE_CHANGE_COMPLETE" : "MSD_CORE_STATE_CHANGE_COMPLETE",
	"EV_PAUSE" : "PAUSE",
	"EV_PLAY" : "PLAY",
	"EV_REMOTE_UPDATE" : "MSD_REMOTE_UPDATE",
	"EV_STATE_CHANGE" : "MSD_STATE_CHANGE",
	
			
	/* Event object properties */
	"EOP_DATA_ID" : "dataId",
	"EOP_UPDATE_DISPLAY_ID" : "updateDisplayId",
	"EOP_AUTOPLAY_EVENT" : "autoplayEvent",
	"EOP_CURRENT_STATE_ID" : "currentStateID",
	
			
	/* General properties - These all need wrapping into data object */
	"AUTOPLAY" : true,
	"AUTOPLAY_DURATION_DEFAULT" : "1000",
	"AUTOPLAY_DURATION_USER_INTERUPTION" : "5000",
	"AUTOPLAY_FOLLOW_USER_CYCLE" : false,
	"AUTOPLAY_FORWARD" : true,
	"IMAGE_COUNT_SEPARATOR" : " / ",
	"LOOP" : true,
	"QUEUE_CHANGE_REQUESTS" : true,


	/*
	=============================
	CONSTRUCTOR
	=============================
	*/
	"init" : function ()
	{
		// Create a new array in which to store data objects
		this._dataStore = new Array();
	},
	
	
	
	/*
	=============================
	PUBLIC MEMBERS
	=============================
	*/
		//
		// @param [jqTarget] : Target jQuery Element
		"updateDisplay" : function (jqTarget, updateDisplayId)
		{
			var t = jqTarget;
			var e = new jQuery.Event(this.EV_REMOTE_UPDATE);
			e[this.EOP_UPDATE_DISPLAY_ID] = updateDisplayId;
			// Trigger update event on target control
			t.trigger(e);
		},

		"pause" : function (jqTarget)
		{
			var t = jqTarget;
			var e = new jQuery.Event(this.EV_PAUSE);
			// Trigger update event on target control
			t.trigger(e);
		},

		"play" : function (jqTarget)
		{
			var t = jqTarget;
			var e = new jQuery.Event(this.EV_PLAY);
			// Trigger update event on target control
			t.trigger(e);
		},
		
	
	/*
	=============================
	PRIVATE PROPERTIES
	=============================
	*/
		
		
		
	/*
	=============================
	PRIVATE METHODS
	=============================
	*/
		
	/* Setup methods */
		
		// [Override]
		//
		// @param [strTarget]	: jqTargetString used to find/return 'jqTarget'
		// @param [jqTarget]	: Target jQuery Element
		"_setup" : function (strTarget, jqTarget)
		{
			var t = jqTarget;
			
			// Get displays
			var displays = jqTarget.find(this.SE_MSD_DISPLAY);
			
			// Record total number of display states
			var totalStates = displays.length;
			
			// Work out current state
			var cf = this.CF_MSD_STATE;
			var currentState;
			if (t.hasClass(cf + 0)) currentState = 0;
			else
			{
				var i;
				var c;
				for (i = totalStates-1; i >= 0; i--)
				{
					c = cf + i;
					if (t.hasClass(c)) { currentState = i; break; };
				}
			}
			
			// Create data object
			var dObj = {};
			dObj[this.DOP_JQ_TARGET] = t;
			dObj[this.DOP_STR_TARGET] = strTarget;
			dObj[this.DOP_TOTAL_STATES]	= totalStates;
			dObj[this.DOP_CURRENT_STATE] = currentState;
			dObj[this.DOP_UPDADE_IN_PROGRESS] = false;
			dObj[this.DOP_AUTOPLAY] = this.AUTOPLAY;
			dObj[this.DOP_AUTOPLAY_DURATION_DEFAULT] = this.AUTOPLAY_DURATION_DEFAULT;
			dObj[this.DOP_AUTOPLAY_DURATION_USER_INTERUPTION] = this.AUTOPLAY_DURATION_USER_INTERUPTION;
			dObj[this.DOP_AUTOPLAY_FORWARD_DEFAULT] = this.AUTOPLAY_FORWARD;
			dObj[this.DOP_AUTOPLAY_FORWARD] = this.AUTOPLAY_FORWARD;
			dObj[this.DOP_AUTOPLAY_FOLLOW_USER_CYCLE] = this.AUTOPLAY_FOLLOW_USER_CYCLE;
			dObj[this.DOP_AUTOPLAY_INSTANCE] = null; // Create instance holder
			dObj[this.DOP_IMAGE_COUNT_SEPARATOR] = this.IMAGE_COUNT_SEPARATOR;
			dObj[this.DOP_LOOP] = this.LOOP;
			dObj[this.DOP_QUEUE_CHANGE_REQUESTS] = this.QUEUE_CHANGE_REQUESTS;
			
			// Store data object
			var dataId = this._storeData(dObj);
			
			// Setup state change links
			this._setupChangeStateLinks(dataId);
			// Setup play / pause controls
			this._setupPlayControls(dataId);

			// Update link states
			if (!this.LOOP) this._updateLinks(dataId, totalStates-1, currentState);
			
			// Update image count display
			this._updateImageCount(dataId);
			
			var __this = this;
			
			// Register to listen for remote update AND control events that are triggered when an external update (uses closure to capture appropriate dataId relevant for given instance)
			t.bind(this.EV_REMOTE_UPDATE, function (e){ __this._handleRemoteUpdate(e, dataId); });
			t.bind(this.EV_PAUSE, function (e){ __this._handlePause(e, dataId); });
			t.bind(this.EV_PLAY, function (e){ __this._handlePlay(e, dataId); });

			// Call subclass setup 'stub' method
			this._setupSubClass(dataId);

			// Assign standard autoplay trigger into state change complete handler
			var __this = this;
			t.bind(this.EV_CORE_STATE_CHANGE_COMPLETE, function (e){ __this._handleCoreStateChangeComplete(e, dataId) } );

			// Setup autoplay functionality
			this._startAutoPlay(dataId, this.AUTOPLAY_DURATION_DEFAULT);
		},
			
			
		// [Abstract method]
		// Override as required
		//
		// @param [dataId] : Reference id for control data within the internal dataStore array
		"_setupSubClass" : function (dataId) {},
			
			
		// Override as required
		//
		// @param [dataId] : Reference id for control data within the internal dataStore array
		"_setupChangeStateLinks" : function (dataId)
		{
			var __this = this;
			
			// Get data
			var d = this._getData(dataId);
			
			// Get target
			var t = d[this.DOP_JQ_TARGET];
			
			// SETUP MENU LINKS:
			//
			// Get standard display links from menu
			var links = t.find(this.SE_MSD_MENU + " " + this.SE_MSD_LINK);
			
			// Assign click functionality to each link
			links.each(
				function (i) {
					$(this).bind("click", function (e){ e.preventDefault(); __this._handleMenuLinkClick(dataId, i, false); })
				}
			);

			// SETUP NEXT/LAST LINKS:
			//
			var next = t.find(this.SE_MSD_LINK_NEXT);
			var prev = t.find(this.SE_MSD_LINK_PREV);
			var ev = this.EV_CLICK_CYCLE;
			next.bind(ev, function (e) { e.preventDefault(); __this._cycleDisplay(dataId, true, false);} );
			prev.bind(ev, function (e) { e.preventDefault(); __this._cycleDisplay(dataId, false, false);} );
		},
		

		// @param [dataId] : Reference id for control data within the internal dataStore array
		"_setupPlayControls" : function (dataId)
		{
			var __this = this;

			// Get data
			var d = this._getData(dataId);
			
			// Get target
			var t = d[this.DOP_JQ_TARGET];

			var play = t.find(this.SE_MSD_LINK_PLAY);
			var pause = t.find(this.SE_MSD_LINK_PAUSE);
			var ev = this.EV_CLICK_PLAYCONTROL;
			play.bind(ev, function (e) { e.preventDefault(); __this.play(t);} );
			pause.bind(ev, function (e) { e.preventDefault(); __this.pause(t);} );
		},

	
	/* Event handlers */
	
		// @param [dataId]			: Reference id for control data within the internal dataStore array
		// @param [targetStateId]	: Id of the state to display
		// @param [autoplayChangeEvent] : [Boolean] indicating whether change instruction was generated by an autoplay event
		"_handleMenuLinkClick" : function (dataId, targetStateId, autoplayChangeEvent)
		{
			// Reset autoplay direction to default
			//
			// Get data
			var d = this._getData(dataId);
			d[this.DOP_AUTOPLAY_FORWARD] = d[this.DOP_AUTOPLAY_FORWARD_DEFAULT];

			// Change display state
			this._changeDisplayState(dataId, targetStateId, autoplayChangeEvent);
		},

		
		// @param [e] : [jqEvent]
		// @param [dataId] : [int]
		"_handlePause" : function (e, dataId)
		{
			// Clear auto play
			this._clearAutoPlay(dataId);
			// Set paused state
			this._setPausedState(dataId);
		},
		
		// @param [e] : [jqEvent]
		// @param [dataId] : [int]
		"_handlePlay" : function (e, dataId)
		{ 
			// Call cycle display which will change the display immediately thus starting the autoplay sequence again
			
			var d = this._getData(dataId);
			this._cycleDisplay(dataId, d[this.DOP_AUTOPLAY_FORWARD], true);
		},

		// @param [e] : [jqEvent]
		// @param [dataId] : [int]
		"_handleRemoteUpdate" : function (e, dataId) { this._changeDisplayState(dataId, e[this.EOP_UPDATE_DISPLAY_ID], false); },
		

		// @param [dataId] : [int] 
		"_handleAutoPlay"  : function (dataId) 
		{
			// Get data
			var d = this._getData(dataId);
			
			// Change (cycle) display
			this._cycleDisplay(dataId, d[this.DOP_AUTOPLAY_FORWARD], true);
		},


		// Override as required
		//
		// @param [e] : [custom jqEventObject]
		// @param [dataId] : [int] Reference id for control data within the internal dataStore array
		"_handleCoreStateChangeComplete" : function (e, dataId)
		{
			// Get data
			var d = this._getData(dataId);
			
			// Work out whether the change state call was generated by user click or autoplay and adjust 'wait duration' accordingly 
			var duration = (e[this.EOP_AUTOPLAY_EVENT]) ? d[this.DOP_AUTOPLAY_DURATION_DEFAULT] : d[this.DOP_AUTOPLAY_DURATION_USER_INTERUPTION];
			this._startAutoPlay(dataId, duration);
		},


	
	/* Display manipulation */
	
		// Update in progress flag
		"_displayUpdateInProgress" : false,
		
		
		// @param [dataId] : 
		// @param [forward] : [Boolean] Indicating whether cycle displays forward
		// @param [autoplayCycle] : [Boolean] Indicating whether the 'cycle display' call was user generated or from the autoplay mechanism (this ultimately dictates the 'pause' duration used on the subsequent autoplay)
		"_cycleDisplay" : function (dataId, forward, autoplayCycle) 
		{
			// Clear any autoplay that might be running
			this._clearAutoPlay(dataId);
			
			// Get data and establish core conditions/properties
			var d = this._getData(dataId);
			var loop = d[this.DOP_LOOP];
			var auto = autoplayCycle;
			
			// Current state (used to calc. next id)
			var cState = d[this.DOP_CURRENT_STATE]; // Current state

			// If queued requests set current id to queued id 
			if (d[this.DOP_QUEUED_STATE_CHANGE]) cState = d[this.DOP_QUEUED_STATE_ID];

			var lastState = d[this.DOP_TOTAL_STATES] - 1; // Total states
			// Target state
			var state = (forward)? ++cState : --cState;
			
			//Set autoplay direction based on whether to follow user cycle commands
			if (d[this.DOP_AUTOPLAY_FOLLOW_USER_CYCLE]) { d[this.DOP_AUTOPLAY_FORWARD] = (forward)? true : false; }

			// If target state too high either loop or set to total based on loop property
			if (state > lastState) state = (loop || auto) ? 0 : lastState;
			
			// If target state too low (< 0) either loop or set to 0
			if (state < 0) state = (loop || auto) ? lastState : 0;
			
			this._changeDisplayState(dataId, state, auto);
		},


		// @param [dataId] : Reference id for control data within the internal dataStore array
		// @param [targetStateId] : Id of the state to display
		// @param [autoplayChangeEvent] : [Boolean] indicating whether change instruction was generated by an autoplay event
		"_changeDisplayState" : function (dataId, targetStateId, autoplayChangeEvent)
		{
			// Clear any autoplay that might be running
			this._clearAutoPlay(dataId);
			
			// Get data
			var d = this._getData(dataId);
			
			// Escape if update in progress (Set in subClases when animation transitions)
			if (d[this.DOP_UPDATE_IN_PROGRESS])
			{
				if (d[this.DOP_QUEUE_CHANGE_REQUESTS]) 
				{
					//else queue requests
					d[this.DOP_QUEUED_STATE_CHANGE] = true;
					d[this.DOP_QUEUED_STATE_ID] = targetStateId;
				}
				return;
			}

			// Clear paused state
			this._clearPausedState(dataId);

			// Get target control
			var t = d[this.DOP_JQ_TARGET];
			
			var state = targetStateId;
			var totalStates = d[this.DOP_TOTAL_STATES];
			
			// Escape if target state id is invalid or currently viewing correct state
			if (state < 0 || state >= totalStates) return;
			
			// Fire state change event
			// 1.Create event object
			var e_start = this._createEventObject(this.EV_STATE_CHANGE, dataId);
			// 2.Trigger event on target
			t.trigger(e_start);
			
			//If not already displaying the correct state then change
			if (!t.hasClass(this.CF_MSD_STATE + targetStateId))
			{
				// Set state on control
				var cf	= this.CF_MSD_STATE;
				var c;
				var i;
				
				// 1.Remove all possible state class names
				for (i = totalStates-1; i >= 0; i--)
				{
					c = cf + i;
					t.removeClass(c);
				}
				
				// 2.Add correct class name for current state
				t.addClass(cf + state);
				
				// Record new state in data
				d[this.DOP_CURRENT_STATE] = state;
			}
			
			// Update links if not looping
			if (!d[this.DOP_LOOP]) this._updateLinks(dataId, totalStates-1, state);

			this._updateImageCount(dataId);

			// Fire state change core functionality complete event
			// 1.Create event object
			var e_complete = this._createEventObject(this.EV_CORE_STATE_CHANGE_COMPLETE, dataId, autoplayChangeEvent);
			e_complete[this.EOP_CURRENT_STATE_ID] = state;
			// 2.Trigger event on target
			t.trigger(e_complete);
		},
		

		// @param [dataId] : Reference id for control data within the internal dataStore array
		// @param [lastState] : [int] Max state possible (last state)
		// @param [currentState] : [int] Current state
		"_updateLinks" : function (dataId, lastState, currentState)
		{
			var __this = this;
			
			// Get data
			var d = this._getData(dataId);

			var t = d[this.DOP_JQ_TARGET];

			// Find links
			var next = t.find(this.SE_MSD_LINK_NEXT);
			var prev = t.find(this.SE_MSD_LINK_PREV);
			
			// Clear click handler from both links
			next.unbind(this.EV_CLICK_CYCLE);
			prev.unbind(this.EV_CLICK_CYCLE);

			// Add 'disabled' class names
			var c = this.CL_LINK_DISABLED;
			var cn = this.CL_LINK_NEXT_DISABLED;
			var cp = this.CL_LINK_PREV_DISABLED;
			next.addClass(c);
			next.addClass(cn);
			prev.addClass(c);
			prev.addClass(cp);

			var ev = this.EV_CLICK_CYCLE;
			if (currentState != lastState)
			{
				next.removeClass(c);
				next.removeClass(cn);
				next.bind(ev, function (e) { e.preventDefault(); __this._cycleDisplay(dataId, true, false);} );
			}
			if (currentState != 0)
			{
				prev.removeClass(c);
				prev.removeClass(cp);
				prev.bind(ev, function (e) { e.preventDefault(); __this._cycleDisplay(dataId, false, false);} );
			}
			
		},


		// @param [dataId] : Reference id for control data within the internal dataStore array
		"_updateImageCount" : function (dataId)
		{
			// Get data
			var d = this._getData(dataId);
			
			// Get target
			var t = d[this.DOP_JQ_TARGET];

			// Get image count
			var ic = t.find(this.SE_MSD_IMAGE_COUNT); 
			
			// Format string
			var s = String(d[this.DOP_CURRENT_STATE] + 1) + d[this.DOP_IMAGE_COUNT_SEPARATOR] + String(d[this.DOP_TOTAL_STATES]); 
			
			// Set image count
			ic.html(s);
		},


		// @param [dataId] : Reference id for control data within the internal dataStore array
		"_setPausedState" : function (dataId)
		{
			// Get data
			var d = this._getData(dataId);
			var t = d[this.DOP_JQ_TARGET];
			t.addClass(this.CL_STATE_PAUSED);
		},
		

		// @param [dataId] : Reference id for control data within the internal dataStore array
		"_clearPausedState" : function (dataId)
		{
			// Get data
			var d = this._getData(dataId);
			var t = d[this.DOP_JQ_TARGET];
			t.removeClass(this.CL_STATE_PAUSED);
		},



	/* Autoplay */
		
		// @param [dataId] : Reference id for control data within the internal dataStore array
		"_clearAutoPlay" : function (dataId)
		{
			// Get data
			var d = this._getData(dataId);

			if (!d) return;

			// Clear specific instance
			window.clearTimeout(d[this.DOP_AUTOPLAY_INSTANCE]);
		},

		// @param [dataId] : Reference id for control data within the internal dataStore array
		// @param [pauseDuration] : [int] Length of time between autoplay cycles
		"_startAutoPlay" : function (dataId, pauseDuration)
		{
			var __this = this;

			// Get data
			var d = this._getData(dataId);

			// Escape if !autoplaying
			if (!d[this.DOP_AUTOPLAY]) return;

			// Clear any pre-existing autoplay instance
			this._clearAutoPlay(dataId);

			// Create new instance
			d[this.DOP_AUTOPLAY_INSTANCE] = window.setTimeout(function (){ __this._handleAutoPlay(dataId); }, pauseDuration);
		},
	


	/* Utility methods */

		// Check if a control is currently paused
		//
		// @param [dataId] : Reference id for control data within the internal dataStore array
		"_controlPaused" : function (dataId)
		{
			var d = this._getData(dataId);
			var t = d[this.DOP_JQ_TARGET];
			return t.hasClass(this.CL_STATE_PAUSED);
		},


	/* Data storage and access */
		
		"_dataStore" : null,
		
		// @param	= data object to store
		//
		// @return	= data reference id
		"_storeData" : function (dataObj) { return (this._dataStore.push(dataObj) -1); },
		
		// @param	= data reference id
		//
		// @return	= data object
		"_getData" : function (id) { return this._dataStore[id]; },
		
	
	/* Internal event object creation */
		
		// Override as required 
		// If overridden ENSURE THAT YOU CALL 'this._super(type, dataId)' to call this method as first step and then build upon the event object;
		//
		// @param [type]	: Event type (string)
		// @param [dataId]	: Reference id for control data within the internal dataStore array
		// @param [autoplayEvent] : [Boolean] Indicating whether autoplayGenerated event
		"_createEventObject" : function (type, dataId, autoplayEvent)
		{
			var o = new jQuery.Event(type);
			o[this.EOP_DATA_ID] = dataId;
			o[this.EOP_AUTOPLAY_EVENT] = autoplayEvent;
			return o;
		}
			
			
});


/*
================================================================================
CLASS NAMES:

// Control container
//
- mrm-msd		: Control root container
- mrm-msd-d-XX	: Current display state (XX = id)

	// Individual display states
	// 
	- mrm-d		: Display state container
	- mrm-d-XX	: Display state UNIQUE id (XX = id)

	// Menu
	// 
	- mrm-msd-menu : Main menu container

		// Menu link
		//
		- mrm-msd-dl	: Menu link
		- mrm-msd-dl-XX	: Menu link state UNIQUE id (XX = id) relates to the corresponding display state

	// Next / previous links
	//
	- mrm-msd-dl-prev	: View 'previous' link
	- mrm-msd-dl-next	: View 'next' link

	// Autoplay control links
	//
	- mrm-msd-dl-play	: Autoplay 'Play' link
	- mrm-msd-dl-pause	: Autoplay 'Pause' link
	
	// Image count display
	//
	- mrm-msd-ic	: Image count display



================================================================================
EXAMPLE HTML:

<div class="mrm-msd mrm-msd-d-0"><!-- ADD CLASS FOR THE DEFAULT DISPLAY DESIRED [e.g. to start on display (0 = 'mrm-msd-d-0') || to start on display (3 = 'mrm-msd-d-3')] -->
		
	<div><!-- OPTIONAL CONTAINER -->
		<div class="mrm-d mrm-d-0"><p>0</p></div>
		<div class="mrm-d mrm-d-1"><p>1</p></div>
		<div class="mrm-d mrm-d-2"><p>2</p></div>
		<div class="mrm-d mrm-d-3"><p>3</p></div>
		<div class="mrm-d mrm-d-4"><p>4</p></div>
		<div class="mrm-d mrm-d-5"><p>5</p></div>
		<div class="mrm-d mrm-d-6"><p>6</p></div>
		<div class="mrm-d mrm-d-7"><p>7</p></div>
		<div class="mrm-d mrm-d-8"><p>8</p></div>
		<div class="mrm-d mrm-d-9"><p>9</p></div>
	</div>

	<ul class="mrm-msd-menu">
		<li class="mrm-msd-dl mrm-msd-dl-0"><a href="#">0</a></li>
		<li class="mrm-msd-dl mrm-msd-dl-1"><a href="#">1</a></li>
		<li class="mrm-msd-dl mrm-msd-dl-2"><a href="#">2</a></li>
		<li class="mrm-msd-dl mrm-msd-dl-3"><a href="#">3</a></li>
		<li class="mrm-msd-dl mrm-msd-dl-4"><a href="#">4</a></li>
		<li class="mrm-msd-dl mrm-msd-dl-5"><a href="#">5</a></li>
		<li class="mrm-msd-dl mrm-msd-dl-6"><a href="#">6</a></li>
		<li class="mrm-msd-dl mrm-msd-dl-7"><a href="#">7</a></li>
		<li class="mrm-msd-dl mrm-msd-dl-8"><a href="#">8</a></li>
		<li class="mrm-msd-dl mrm-msd-dl-9"><a href="#">9</a></li>
	</ul>

	<a href="#" class="mrm-msd-dl-prev">Previous</a>
	<a href="#" class="mrm-msd-dl-next">Next</a>

	<a href="#" class="mrm-msd-dl-play">Play</a>
	<a href="#" class="mrm-msd-dl-pause">Pause</a>

	<h6 class="mrm-msd-ic">0 / 0</h6>
</div>

*/
