// JavaScript for animating strokes
// Copyright Alex Amies, 2007

// Namespace
chinesenotes =  new Object();

/**
 * JavaScript object to represent a series of strokes making up a character.
 * An array will be formed by taking a base name and appending integers to 
 * it.
 * @param baseName The base name of the image files
 * @param numImages The number of image files
 *
 * Example use:
 * var bai2 = new chinesenotes.StrokeImages("bai2_str", 5, ".png");
 *
 */
chinesenotes.StrokeImages = function(baseName, numImages, postfix) {
    this.baseName = baseName;
    this.numImages = numImages;
    this.postfix = postfix;
}

chinesenotes.StrokeImages.prototype = {

	/**
	 * Returns a chinesenotes.Character with the given name.
	 */
	getCharacter: function(name) {
		var imageArray = new Array();
		for (var i=0; i<this.numImages; i++) {
			imageArray[i] = this.baseName + (i+1) + this.postfix;
		}
		return new chinesenotes.Character(imageArray, name);
	}
	
}

/**
 * JavaScript object to represent a character.
 * @param strokeImages Array of names of image files that show strokes
 * @param name The name of the character (optional)
 *
 * Example use:
 * var images = [
 * 		"images/bai2_str1.png", 
 * 		"images/bai2_str2.png", 
 * 		"images/bai2_str3.png", 
 * 		"images/bai2_str4.png", 
 * 		"images/bai2_str5.png"
 * 		];
 * var bai2 = new chinesenotes.Character(images);
 *
 */
chinesenotes.Character = function(strokeImages, name) {
    this.strokeImages = strokeImages;
    this.name = name;
}

/**
 * JavaScript gadget to animate strokes for a series of characters.
 * @param divId ID of the HTML element to display the images in
 * @param characterArray Array of chinesenotes.Character objects
 * @param playId ID of the HTML element that, when clicked, should animate the display (optional)
 * @param stopId ID of the HTML element that, when clicked, should stop animating the display (optional)
 * 
 * Example use:
 * var images = [
 * 		"images/bai2_str1.png", 
 * 		"images/bai2_str2.png", 
 * 		"images/bai2_str3.png", 
 * 		"images/bai2_str4.png", 
 * 		"images/bai2_str5.png"
 * 		];
 * var bai2 = new chinesenotes.Character(images);
 * new chinesenotes.CharSeriesStrokeGadget("strokesDiv", [bai2], "play", "stop");
 *
 */
chinesenotes.CharSeriesStrokeGadget = function(divId, characterArray, playId, stopId) {

	// Track animation step
    var strokesGadgetArray = new Array();
    this.i = 0;
    
    // When one character has finished animating, move to the next one
    var nextCharFn = function() {
        this.i++;
    	if (this.i < characterArray.length) {
    		strokesGadgetArray[this.i].play.call(strokesGadgetArray[this.i]);
    	} else {
    		this.i = 0;
    	}
    }
    var thisGadget = this;
    // Called with this in a different context
    var thisNextCharFn = function() {
    	nextCharFn.call(thisGadget);
    }

	// Create an animation gadget for each character
    for (var j=0; j<characterArray.length; j++) {
    
        var charObject = characterArray[j];
        var animateOnLoad = false;
        if (j == 0) {
        	animateOnLoad = true;
        }
        strokesGadgetArray[j] = new chinesenotes.StrokesGadget(
           		divId, 
           		characterArray[j].strokeImages,
           		null,
           		null,
           		animateOnLoad,
           		thisNextCharFn
           		);
    }

    // Respond to a play click
    if (playId) {
    	var play = function() {
			if (this.i >= characterArray.length) {
	    		this.i = 0;
			}
        	strokesGadgetArray[this.i].play.call(strokesGadgetArray[this.i]);
    	}
    	var playThis = function() {
    		play.call(thisGadget);
			return false;
    	}
		var playLink = document.getElementById(playId);
		playLink.onclick = playThis;
    }

    // Respond to a stop click
    if (stopId) {
    	var stop = function() {
        	strokesGadgetArray[this.i].stop.call(strokesGadgetArray[this.i]);
    	}
    	var stopThis = function() {
    		stop.call(thisGadget);
			return false;
    	}
		var stopLink = document.getElementById(stopId);
		stopLink.onclick = stopThis;
    }
}

/**
 * JavaScript gadget to animate strokes.
 * @param divId ID of the HTML element to display the images in
 * @param imageArray Array of names of image files to animate
 * @param playId ID of the HTML element that, when clicked, should animate the display (optional)
 * @param stopId ID of the HTML element that, when clicked, should stop animating the display (optional)
 * @param playOnStartup A boolean parameter that, if true, indicates the image should be animated on startup 
 *                      (optional)
 * @param finnishedCallback A function to call when the animation has completed a full cycle (optional)
 * 
 * Example use:
 * var images = [
 * 		"images/bai2_str1.png", 
 * 		"images/bai2_str2.png", 
 * 		"images/bai2_str3.png", 
 * 		"images/bai2_str4.png", 
 * 		"images/bai2_str5.png"
 * 		];
 * new chinesenotes.StrokesGadget("strokesDiv", images);
 *
 */
chinesenotes.StrokesGadget = function(divId, imageArray, playId, stopId, playOnStartup, finnishedCallback) {

	this.divId = divId;
    this.imageArray = imageArray;
    this.finnishedCallback = finnishedCallback;

    // for remembering place in image animation 
    this.i = 0;
    this.intervalID = 0;
	
    // Respond to play clicks
    var thisGadget = this;
    if (playId) {
        var playThis = function() {
            thisGadget.play.call(thisGadget);
            return false;
        }
        var playLink = document.getElementById(playId);
        playLink.onclick = playThis;
    }
    if (playOnStartup) {
		this.play();
    }
	
    // Respond to stop clicks
    if (stopId) {
        var stopThis = function() {
            thisGadget.stop.call(thisGadget);
            return false;
        }
        var stopLink = document.getElementById(stopId);
		stopLink.onclick = stopThis;
    }
}

// Methods for StrokesGadget
chinesenotes.StrokesGadget.prototype = {
    
    /**
     * Start or restart animation of the character
     */
    play: function() {
		var animate = function() {
	    	if (this.i < this.imageArray.length) {
	    		if (!this.image) {
    				var div = document.getElementById(this.divId);
	    		    this.image = document.createElement("img");
	    		    this.image.src = this.imageArray[this.i++];
    				div.appendChild(this.image);
	    		} else {
					this.image.src = this.imageArray[this.i++];
				}
	    	} else {
	    	    clearInterval(this.intervalID);
	    		this.i = 0;
    	    	if (this.finnishedCallback) {
                	this.finnishedCallback();
	    		}
	    	}
		}
		thisGadget = this;
		var animateThis = function() {
			animate.call(thisGadget);
		}
        this.intervalID = setInterval(animateThis, 1000);
    },

    /**
     * Stop animation of the character
     */
    stop: function() {
        clearInterval(this.intervalID);
    }
}

/** 
 * Open a window for showing stroke detail
 */
chinesenotes.openWindow = function(page) {
    window.open(page, "Strokes", "width=400,height=400,status=no,resizeable=yes");
}

/** 
 * Open a larger window for showing stroke detail
 */
chinesenotes.openLargeWindow = function(page) {
    window.open(page, "Strokes", "width=500,height=550,status=no,resizeable=yes");
}