/******************************************************************************
 * WPF/E UTILITY CODE
 *****************************************************************************/

/******************************************************************************
 * Helper method for creating per-object callbacks
 * @param target object to invoke the callback on
 * @param callback method to be called on the object
 *****************************************************************************/
function delegate(target, callback) {
	var func = function() {
		callback.apply(target, arguments);
	}
	return func;
}


/******************************************************************************
 * Hook up the specified event to the specified delegate.
 * Allows javascript delegates to be used and dynamically
 * creates the global method.
 * @param target WPF/e element to set the event on
 * @param eventName name of the event to set, ie "MouseEnter"
 * @param delegate function to call when the event occurs.
 *****************************************************************************/
function setCallback(target, eventName, delegate) {
	if (!window.methodID)
		window.methodID = 0;
	
	var callbackName = "uniqueCallback" + (window.methodID++);
	eval(callbackName + " = delegate;");
	
	target.SetValue(eventName, "javascript:" + callbackName);
}

// global variable for handoff
var mainHandoffCollection = [];
/******************************************************************************
 * handsoff storyboards one to the other
 * requires the global variable handoffCollection of type array
 * @param storyboard the storyboard you want to start
 * @param the array collection of storyboards for the handoff.
 *****************************************************************************/
function handoff( storyboard, handOffCollection ) {
    var len = handOffCollection.push(storyboard)    
    storyboard.begin();
    if(len > 1) {
        handOffCollection.shift().stop();        
    }
}

/******************************************************************************
 * Creates an XML Object checking for browser type
 * @return the xml object if successful, false if not
 *****************************************************************************/
function createXmlObj(){
    var httprequest = false;
    if (window.XMLHttpRequest) { // if Mozilla, Safari etc
        httprequest = new XMLHttpRequest();
        if (httprequest.overrideMimeType)
            httprequest.overrideMimeType('text/xml');
    }
    else if (window.ActiveXObject){ // if IE
        try {
            httprequest=new ActiveXObject("Msxml2.XMLHTTP");
        } 
        catch (e){
            try{
                httprequest=new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch (e){}
        }
    }
    return httprequest;
}

/******************************************************************************
 * Replaces all instances of the given substring
 *
 * @param strTarget The substring you want to replace
 * @param strSubString The string you want to replace in.
 * @return The updated string with replacements
 *****************************************************************************/
String.prototype.replaceAll = function( strTarget, strSubString ){
    var strText = this;
    var intIndexOfMatch = strText.indexOf( strTarget );
     

    // Keep looping while an instance of the target string
    // still exists in the string.
    while (intIndexOfMatch != -1){
        // Relace out the current instance.
        strText = strText.replace( strTarget, strSubString )
         

        // Get the index of any next matching substring.
        intIndexOfMatch = strText.indexOf( strTarget );
    }
 

    // Return the updated string with ALL the target strings
    // replaced out with the new substring.
    return( strText );
}

/******************************************************************************
	Simple little class to help downloading multiple files at once.
	@param base the base directory to download from (prepended to all URIs)
	
	use:
	var loader = new Loader("xaml");
	loader.uris.push("hex.xaml");
	loader.uris.push("Concrete1.xaml");
	loader.uris.push("Concrete2.xaml");
	loader.uris.push("Concrete3.xaml");
	
	loader.completed = delegate(this, this.handleLoadStateChange);
	
	Gameboard.prototype.handleLoadStateChange = function(responses) {	
		this.baseXaml = responses["hex.xaml"];
		concrete1Xaml = responses["Concrete1.xaml"];
		concrete2Xaml = responses["Concrete2.xaml"];
	}
*****************************************************************************/
function Loader(base) {
	this.base = base;
	this.uris = new Array();
	this.results = new Object();
}

Loader.prototype.index = 0;
Loader.prototype.completed = null;
Loader.prototype.xhr = null;

Loader.prototype.start = function() {
	if (this.uris.length <= this.index) {
		this.handleCompleted();
		return;
	}
	try {
		this.xhr = createXmlObj();
		this.xhr.onreadystatechange = delegate(this, this.handleLoadStateChange);
		if (this.base)
			this.xhr.open("GET", this.base + "/" + this.uris[this.index], true);
		else
			this.xhr.open("GET", this.uris[this.index], true);
		this.xhr.send(null);
	}
	catch(e) {
		alert("This sample must be run from a local web server");
	}
}

Loader.prototype.handleLoadStateChange = function() {
	if (this.xhr.readyState == 4 && this.xhr.status == 200) {
		var uri = this.uris[this.index];
		this.results[uri] = this.xhr.responseText;
		++this.index;
		
		this.start();
	}
}

Loader.prototype.handleCompleted = function() {
	if (this.completed != null)
		this.completed(this.results);
}

// http://adomas.org/javascript-mouse-wheel/
function WheelHelper() {
	this.delegate = delegate(this, this.handleMouseWheel);
	if (window.addEventListener) {
		// DOMMouseScroll is for mozilla.
		window.addEventListener('DOMMouseScroll', this.delegate, false);
	}
	// IE/Opera.
	window.onmousewheel = document.onmousewheel = this.delegate;
}

WheelHelper.prototype.wheelScrolled = null;
WheelHelper.prototype.delegate = null;

WheelHelper.prototype.handleMouseWheel = function(event) {
	var delta = 0;
    if (!event) // For IE.
		event = window.event;
		
    if (event.wheelDelta) { //IE/Opera.
		delta = event.wheelDelta/120;
		// In Opera 9, delta differs in sign as compared to IE.
		if (window.opera)
			delta = -delta;
    }
    else if (event.detail) { // Mozilla case.
		// In Mozilla, sign of delta is different than in IE.
		// Also, delta is multiple of 3.
		delta = -event.detail/3;
    }
	// If delta is nonzero, handle it.
	// Basically, delta is now positive if wheel was scrolled up,
	// and negative, if wheel was scrolled down.
	if (delta && this.wheelScrolled)
		this.wheelScrolled(delta);
		
	// Prevent default actions caused by mouse wheel.
	// That might be ugly, but we handle scrolls somehow
	// anyway, so don't bother here..
	if (event.preventDefault)
		event.preventDefault();
		
	event.returnValue = false;
}

WheelHelper.prototype.detach = function() {
	if (this.delegate != null) {
		if (window.removeEventListener) {
			window.removeEventListener('DOMMouseScroll', this.delegate, false);
		}
		
		// IE/Opera.
		window.onmousewheel = document.onmousewheel = null;
		
		this.delegate = null;
	}
}