/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 */

/**
 * ddjs.js
 *
 * Main javascript file
 *
 * File Path: /scripts/
 *
 * $Id: ddjs.js 136 2007-02-15 18:17:20Z topdog $
 *
 * LICENSE: copyright 2005, 2006 Edward Vermillion - Doggydoo Codeworks. Unless
 * otherwise stated ALL RIGHTS ARE RESERVED. Use or reuse without prior
 * written permission from the author or Doggydoo Codeworks is prohibited.
 * Visit http://www.doggydoo.net/license/v2.x for the full license.
 * Installation and use of this software implies agreement to the full
 * license.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DOGGYDOO
 * CODEWORKS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @package     DD-CMS
 * @author      Edward Vermillion <evermillion@doggydoo.net>
 * @copyright   2005, 2006 Edward Vermillion, Doggydoo Codeworks
 * @license     http://www.doggydoo.net/license/v2.x
 * @version     2.0.2
 */
 
/**
 * This is the namespace container for DDJS
 */
var DDJS = new function () {

    /**
     * @type String The root directory for the site
     */
    this.baseDir = '';

    /**
     * @type Array    An array for loading off-screen images
     */
    this.imageCache = new Array();

    /**
     * @type Int    Image identifier for the imageCache array
     */
    this.icc = 1;

    /**
     * @type Int     Number of images from the document.images array
     */
    this.numImages = 0;

    /**
     * @type Int   Number of images loaded by the browser
     */
    this.loadedImages = 0;

    /**
     * @type Boolean Are we dealing with Internet Explorer
     */
    this.isIE = false;

    /**
     * @type Array Array of subordinate objects that require initialization after
     *             the page has loaded.
     */
    this.initCache = new Array();

    /**
     * addInit method
     *
     * Adds an object to the initCache array
     */
    this.addInit = function (obj) {
        this.initCache.push(obj);
    };

    /**
     * initSubs method
     *
     * Initializes objects in the initCache array
     */
    this.initSubs = function () {
        var n = this.initCache.length;
        var i;

        for (i=0; i < n; i++) {
            this.initCache[i].init();
        }
    };

    /**
     * swapImage method
     *
     * This method swaps the image src value for a given image object. If the
     * browser is IE and needs the png fix from iemunge.js then the swapPNG
     * method of that object is called, otherwise the src for the image object
     * is reset to the newSrc value.
     *
     * @param Object imgObj    HTMLImageElement
     * @param String newSrc    src of new image
     */
    this.swapImage = function (imgObj, newSrc) {
        if (this.isIE && newSrc.lastIndexOf('.png') != -1 && imgObj.doIE != 'false') {
            this.IE.swapPNG(imgObj, newSrc);
        } else {
            imgObj.src = newSrc;
        }
    };

    /**
     * cacheImage method
     *
     * This method adds an image to the off-screen browser image cache array
     *
     * @param String imgSrc   The src value of the image
     */
    this.cacheImage = function (imgSrc) {
        this.imageCache[this.icc] = new Image();
//      this.imageCache[this.icc].onload = alert(imgSrc + ': loaded');
        this.imageCache[this.icc].src = imgSrc;
        this.icc++;
    };

    /**
     * loadPage method
     *
     * This method is used to do any necessary page initializations and should
     * be called by from the global initPage() function from the body.onload
     * event.
     *
     * All <img /> tags *must* include an onload="Main.countImage(this);" or the
     * page will hang indefinately. It will also hang if one of the images fails
     * to load.
     *
     * If there are not going to be any .png images then comment out the section
     * for png's below and ignore the countImages() bits.
     */
    this.loadPage = function (div) {

        /**
         * Deffer display of the page contents until all images are loaded into
         * the browser to keep the IE PNG fix from 'blinking' the PNG images
         * that are 'fixed'.
         */
        var mainDiv = document.getElementById(div);

        this.numImages = document.images.length;

        if (this.isIE && this.IE.needPNGFix) {
            
            var loadTimer = new this.TimerClass();
            loadTimer.startTimer(10000);
            
            while (this.numImages > this.loadedImages) {
                // Loop until all the images are loaded...
                if (loadTimer.checkTime() == 0) {
                    // Or until we get tired of waiting for them...
//                  alert('Some images failed to load in the allotted time');
                    break;
                }
                continue;
            }
            
            this.IE.checkPNGs();
        }

        mainDiv.style.visibility = 'visible';
        /**
         * End PNG deffer section...
         */

        this.initSubs();
    };

    /**
     * countImage method
     *
     * Tracks the number of images loaded in the browser. All images should have
     * an onload="Main.countImage();" event. 
     */
    this.countImage = function (imageObj) { 
        this.loadedImages++; 
    };

    /**
     * generateRandomString method
     *
     * Generates a quazi-random string.
     *
     * @param Int stringLength  The length of the string to be generated
     */
    this.generateRandomString = function (stringLength) {
    	var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
    	var randomstring = '';
    	for (var i = 0; i < stringLength; i++) {
    		var rnum = Math.floor(Math.random() * chars.length);
    		randomstring += chars.substring(rnum,rnum+1);
    	}
    	return randomstring;
    };
}

/**
 * A generic timer class
 */
DDJS.TimerClass = function () {

    /**
     * @type integer - Timestamp of the end of the timed period
     */
    this._end = 0;

    /**
     * startTimer method
     * 
     * Starts a timing session
     * 
     * @param limit integer - Time span, in microseconds
     */
    this.startTimer = function (limit) {
        var now = Date.parse(Date());
        var end = (now + limit);
        var endTime = new Date();
        endTime.setTime(end);
        this._end = endTime.getTime();
    };

    /**
     * checkTime method
     * 
     * Returns the time remaining for the session, or 0 if the time has elapsed
     * 
     * @return integer
     */
    this.checkTime = function () {
        if (this._end == 0) {
            return 0;
        }
        var now = Date.parse(Date());
        var ret = this._end - now;
        
        if (ret <= 0) {
            ret = 0;
            this.resetTimer();
        }
        return ret;
    };
    
    /**
     * resetTimer method
     * 
     * Clears the time remaining for the session
     */
    this.resetTimer = function () {
        this._end = 0;
    };
}

