﻿//******************************************************************************
// Author: Paul Irish
// Date: 2/2/2007
// File: RunEzUI.js
// Description: Functions to navigate the World UI
//******************************************************************************

//*******************************************
// Function: Onload function 
// Description: Loads functions before the page is done loading. IE6+, FF, Opera, Saf2
// Author: Dean Edwards/Matthias Miller/John Resig
//*******************************************     	
function init() {
	// quit if this function has already been called
	if (arguments.callee.done) return;

	// flag this function so we don't do the same thing twice
	arguments.callee.done = true;

	// kill the timer
	if (_timer) clearInterval(_timer);

	///////////////////////////////////////////
	// here is where we put our onload events//
	///////////////////////////////////////////
	
	if ( $('tile-wrap') ){
	// if we're in the world view, run these
		resizeo();
		initMiniMap();
    }
    
    //always run these
    
    initCB(); // custom boxes
    adjustlinks();
};

/* for Mozilla/Opera9 */
if (document.addEventListener) {
	document.addEventListener("DOMContentLoaded", init, false);
}

/* for Internet Explorer */
/*@cc_on @*/
/*@if (@_win32)
	document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
	var script = document.getElementById("__ie_onload");
	script.onreadystatechange = function() {
		if (this.readyState == "complete") {
			init(); // call the onload handler
		}
	};
/*@end @*/

/* for Safari */
if (/WebKit/i.test(navigator.userAgent)) { // sniff
	var _timer = setInterval(function() {
		if (/loaded|complete/.test(document.readyState)) {
			init(); // call the onload handler
		}
	}, 10);
}

/* for other browsers */
window.onload = init;

//////////////////////
// Globals.
/////////////////////

//var islands = ['watchframe','homeframe','hearframe','mapframe','gearframe', 'sayframe'];
//var droppers = ['db0','db1','db2','db3','db4', 'db5'];
 
var winWidth = 0, winHeight = 0;
var currentIsland = 'homeframe';
var delaytrue;

function Island(id,dropper,files){
	this.id = id;
	this.dropper = dropper;
	this.files = files;
}

//all file name should be lower case.
var watch = new Island('watchframe', 'db0', [ 'watch.aspx','watchsoon.aspx','videos.aspx','videobrowse.aspx','videodisplay.aspx','videoeditor.aspx','videopublish.aspx','videosaved.aspx' ]);
var home = new Island('homeframe', 'db1', [ 'default.aspx', 'logout.aspx' ]);
var hear = new Island('hearframe','db2',['hear.aspx','playlistdirectory.aspx']);
var mapi = new Island('mapframe','db3',['browseruns.aspx','viewrun.aspx']);
var gear = new Island('gearframe','db4',['createrun.aspx']);
var say = new Island('sayframe','db5',['say.aspx','browse_groups.aspx', 'post_topic.aspx', 'group.aspx','createnewgroup.aspx','create_posting.aspx','search_groups.aspx','topic.aspx','runeasyprofile.aspx','jointhisgroup.aspx']);

var islands = [watch,home,hear,mapi,gear,say];

//*******************************************
// Function: initMiniMap
// Description: Sets up minimap
// Author: Paul Irish
//*******************************************
function initMiniMap() {

  	new Draggable('miniCurrent',{
		snap: function(x,y) {
		  return[  
			x<88 ? (x > 0 ? x : 0 ) : 88,  // these are pixel bounds for the top left corner
			y<32 ? (y > 0 ? y : 0) : 32];
		}
		//,    revert:true
	});
  
	document.getElementsByClassName('dropbox').each( function(el) { // for all of our droppers... TODO change this to use datastructure instead
	    
	    Event.observe(el, 'click', function(e){
	        console.log("minimap click event, href=" + Event.element(e).href);
	        navigateTo(Event.element(e).href );
	        Event.stop(e);
	        return false;
	    });
		
		Droppables.add(el,{
			onDrop:function(el, dropel){
				islands.each( function(el){ 
					if (el.dropper == dropel.id) {
					    console.log("ondrop event, href=" + dropel.href);
	                    navigateTo(dropel.href );
					}
				});
			}
		}); // end of droppables.add
	}) // end of each 
	
    container = 'tile-wrap'; // manually set because this isn't changing
    Position.prepare();
    /*
    var container_x = Position.cumulativeOffset($(container))[0];
    var element_x = Position.cumulativeOffset($(islands[1].id))[0];
    var container_y = Position.cumulativeOffset($(container))[1];
    var element_y = Position.cumulativeOffset($(islands[1].id))[1];
 	$(container).scrollLeft = element_x - container_x;
 	$(container).scrollTop = element_y - container_y;
 	*/
}

function initYahooHistory(){
    var bookmarkedSection = YAHOO.util.History.getBookmarkedState( "section" ); // url.html#section=something
    var querySection = YAHOO.util.History.getQueryStringParameter( "section" ); // url.html?section=somethingelse
    var initSection = bookmarkedSection || querySection || "Default.aspx"; // pick the best one. default to home.
    // Register our only module. Module registration MUST take
    // place before calling YAHOO.util.History.initialize.
    YAHOO.util.History.register( "section", initSection, function( state ) {
	    // This is called after calling YAHOO.util.History.navigate, or after the user
	    // has trigerred the back/forward button. We cannot discrminate between
	    // these two situations.
	    console.log("Changing to state: " + state);
	    Pan(state);
    } );
    
    YAHOO.util.History.onLoadEvent.subscribe( function() { 
        console.log("history onloadevent, state = " + YAHOO.util.History.getCurrentState( "section" ));
        Pan(decodeURIComponent(YAHOO.util.History.getCurrentState( "section" )));
    });
}

function adjustlinks(){
	$$("a").each( function(a){   // go through all of the links on the page
	     if(a.getAttribute('href')!="#" && !a.hasClassName("external") && a.target==""){
		     if(typeof(a.adjusted)=="undefined"){
		         a.adjusted=true;
		         Event.observe(a, 'click', function(e){
		            console.log("a.href=" + Event.findElement(e,"a").href);
		            navigateTo(Event.findElement(e,"a").href);
	                Event.stop(e);
	                return false;
		         });
		      }
		 }
	});
}

function navigateTo(url){
    console.log("navigateTo called with: " + url);
    if(window.top==window){
        var parsed;
        if(url.indexOf("://")==-1){
            //relative url
            parsed=parseUri("/" + url); //WARNING: This is a ridiculous HACK
        }else{
            //absolute url
            parsed = parseUri(url);
        }
        var state = parsed.fileName + (parsed.query==""?"":("?" + parsed.query));
        if(typeof(YAHOO)=="object" && typeof(YAHOO.util)=="object" && typeof(YAHOO.util.History)=="object"){
            YAHOO.util.History.navigate( 'section', state );
        }else{
            window.location.href=url;
        }
    }else{
        window.top.navigateTo(url);
    }
}

//*******************************************
// Function: parseUri JS v0.1
// Splits any well-formed URI into parts. Returns an object.
// Author: Steven Levithan (http://badassery.blogspot.com)
// Source: http://badassery.blogspot.com/2007/02/parseuri-split-urls-in-javascript.html
//*********************************************

/* 
Splits any well-formed URI into the following parts (all are optional):
----------------------
• source (since the exec() method returns backreference 0 [i.e., the entire match] as key 0, we might as well use it)
• protocol (scheme)
• authority (includes both the domain and port)
    • domain (part of the authority; can be an IP address)
    • port (part of the authority)
• path (includes both the directory path and filename)
    • directoryPath (part of the path; supports directories with periods, and without a trailing backslash)
    • fileName (part of the path)
• query (does not include the leading question mark)
• anchor (fragment)
*/
function parseUri(sourceUri){
    var uriPartNames = ["source","protocol","authority","domain","port","path","directoryPath","fileName","query","anchor"];
    var uriParts = new RegExp("^(?:([^:/?#.]+):)?(?://)?(([^:/?#]*)(?::(\\d*))?)?((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[\\?#]|$)))*/?)?([^?#/]*))?(?:\\?([^#]*))?(?:#(.*))?").exec(sourceUri);
    var uri = {};
    
    for(var i = 0; i < 10; i++){
        uri[uriPartNames[i]] = (uriParts[i] ? uriParts[i] : "");
        
        
        // sub function for query arguments. 
        // to access the value of a URL variable: parseUri(window.location).queryVars.MyURLVar 
        if ( uriParts[i] && uriPartNames[i] == 'query' ) {
		uri['queryVars'] = {};
		var qString = uriParts[i];
		qString = qString.split('&');
		for (var j=0; j<qString.length; j++) {
			var qVar = qString[j].split('=');
			var qKey = qVar[0];
			var qVal = qVar[1];
			uri['queryVars'][qKey] = qVal;
			}
		}
    }
    
    // Always end directoryPath with a trailing backslash if a path was present in the source URI
    // Note that a trailing backslash is NOT automatically inserted within or appended to the "path" key
    if(uri.directoryPath.length > 0){
        uri.directoryPath = uri.directoryPath.replace(/\/?$/, "/");
    }
    
    return uri;
}
  
//*******************************************
// Function: Pan
// Description: Interfaces with dhtmlhistory and moveTo
// Author: Paul Irish
//*******************************************     
//parameter "url" is the url to navigate to.
function Pan(url){
	Lightbox.hideAll(); // kill any lightboxes.
	
	var parsed;
	
	if(url.indexOf("://")==-1){
        //relative url
        parsed=parseUri("/" + url); //WARNING: This is a ridiculous HACK
    }else{
        //absolute url
        parsed = parseUri(url);
    }
	islands.each( function(el){     	// look through the islands object
		if (el.files.indexOf(parsed.fileName.toLowerCase()) != -1){   // if we find a filename that matches our hash
			 moveTo(el.id, el.dropper, url);      // move the view to that island
	    }
	});
  
}

//*******************************************
// Function: moveTo
// Description: Moves the viewport to the right island.
// Author: Paul Irish
//*******************************************     	
function moveTo(newIslandElement, dropper, url){
    console.log("moveTo called with url " + url);
	// move the thumbnail control outline
	new Effect.Move (
			$('miniCurrent'),
			{ x: $(dropper).offsetLeft, y: $(dropper).offsetTop, mode: 'absolute', duration: 0.2}
	);
	
		
	if (currentIsland != newIslandElement){  // are we actually changing the screen? if yes...
		if (currentIsland) // if we're not staring at the homepage...
			$(currentIsland).scrolling = "no";  // i dont want a scrollbar on unused ones. TODO might just clear the iframe content??
		
		delaytrue = 1000; // we need that pause on the src change
		currentIsland = newIslandElement; // we got a new one!
	}
	else {
		delaytrue = 1; // no pause on the src change
	}
	
	$(currentIsland).scrolling = "auto"; 		

	// move the big screen
    container = 'tile-wrap'; // manually set because this isn't changing
    var container_x = Position.cumulativeOffset($(container))[0];
    var element_x = Position.cumulativeOffset($(newIslandElement))[0];
    var container_y = Position.cumulativeOffset($(container))[1];
    var element_y = Position.cumulativeOffset($(newIslandElement))[1];

    new Effect.Scroll(container, {x:(element_x-container_x), y:(element_y-container_y)});
    //TODO this is a wicked hack
    setTimeout(function(){$(newIslandElement).src = url},delaytrue); // delay so that panimation is as smooth as possible
}

//*******************************************
// Function: Cross Browser Window Size
// Description: winWidth, winHeight are the dimensions of the browser screen size.
// Author: http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
//*******************************************     	

function getwindowsize() {
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    winWidth = window.innerWidth;
    winHeight = window.innerHeight;
  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    winWidth = document.documentElement.clientWidth;
    winHeight = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    winWidth = document.body.clientWidth;
    winHeight = document.body.clientHeight;
  }
}

	
	
//*******************************************
// Function: Resizeo
// Description: Adjustments when the browser window is resized.
// Author: Paul Irish
//*******************************************     	
		
	
window.onresize = function(){  resizeo(); }; // this function ALSO runs on onload.

function resizeo() {
	getwindowsize(); // get our new numbers
	if(winWidth > 1450)
	{
		var widthdiff = (winWidth - 1450) * -1;	
		//resize the browser window
		alert('Sorry, we need to resize your browser window to provide a better experience for  you.');
		window.resizeBy(widthdiff, 0 );
	}
		
	if ($('tile-wrap') == null) return;  // get out of here if you're not the world view.
	
	$('tile-wrap').style.height = winHeight + 'px';  // adjust the main viewport's height. (width will always be 100%)

	$$('.iframes').each( function(el) {      // go through our islands and adjust their sizes
		el.style.height = winHeight + 'px';
		el.style.width = winWidth + 'px';
	});
};	
	
	

	
//*******************************************
// Function: Scroll Constructor
// Description: This doesn't yet have support for sinoidal, exponential math, etc.
// Author: ?
//*******************************************        
Effect.Scroll = Class.create();
Object.extend(Object.extend(Effect.Scroll.prototype, Effect.Base.prototype), {
  initialize: function(element) {
    this.element = $(element);
    var options = Object.extend({
      x:    0,
      y:    0,
      mode: 'absolute'
    } , arguments[1] || {}  );
    this.start(options);
  },
  setup: function() {
    if (this.options.continuous && !this.element._ext ) {
      this.element.cleanWhitespace();
      this.element._ext=true;
      this.element.appendChild(this.element.firstChild);
    }
   
    this.originalLeft=this.element.scrollLeft;
    this.originalTop=this.element.scrollTop;
   
    if(this.options.mode == 'absolute') {
      this.options.x -= this.originalLeft;
      this.options.y -= this.originalTop;
    } else {
   
    }
  },
  update: function(position) {   
    this.element.scrollLeft = this.options.x * position + this.originalLeft;
    this.element.scrollTop  = this.options.y * position + this.originalTop;
  }
});




