/******************************************************************************
 * 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;");
    
    //eval('target.'+eventName+'= "'+callbackName+'";');
    target.addEventListener(eventName, ""+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();        
    }
}

/******************************************************************************
 * 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, control) {
    this.base = base;
    this.uris = new Array();
    this.results = new Object();
    this.wpfe = control;
}

Loader.prototype.createDownloaderObj = function(){
    var downloader = false;
    try {
        downloader=this.wpfe.createObject("Downloader");
    } 
    catch (e){}
    return downloader;
}

Loader.prototype.index = 0;
Loader.prototype.completed = null;
Loader.prototype.downloader = null;

Loader.prototype.start = function() {
    if (this.uris.length <= this.index) {
        this.handleCompleted();
        return;
    }
    
    try {
        this.downloader = this.createDownloaderObj();
        setCallback(this.downloader, "downloadProgressChanged", delegate(this, this.handleDownloadProgressChanged));
        setCallback(this.downloader, "completed", delegate(this, this.handleNextDownload));
        this.downloader.open("Get", this.base + "/" + this.uris[this.index]);
        this.downloader.send();
    } catch (e) {
        if (e.message = "Access is denied") {
            alert("This sample needs to be run from a web server or Visual Studio 2005");
        }
        else {
            alert("Warning: An error occurred retrieving configuration files for this sample and it may not function correctly");
        }
    }
}

Loader.prototype.handleDownloadProgressChanged = function(sender)
{
    // window.status = sender.downloadProgress;
    // cannot do anything meaningful here
}

Loader.prototype.handleNextDownload = function(args) {
    if (args.status == 200) {
        var uri = this.uris[this.index];
        this.results[uri] = args.responseText;
        ++this.index;
        this.start();
    }
}

Loader.prototype.handleCompleted = function() {
    if (this.completed != null)
        this.completed(this.results);
}