﻿
//  CONSTANTS FOR ARRAY ACCESS
var ID = 0;
var OBJECT = 1;
var MIN_HEIGHT = 2;
var MAX_HEIGHT = 3;
var MIN_WIDTH = 4;
var MAX_WIDTH = 5;
var EXPAND_TYPE = 6;
var EXPANDED_FLAG = 7;

var AnimatedWidget = {

    //  DEFINE THE EXPANSION OPTIONS
    Horizontal: 1,
    Vertical: 2,
    Both: 3,

    DivArray: new Array(),
    DivCount: 0,
    DivExpand: null,
    DivCollapse: new Array(),

    SlideActive: false,
    SlideProcess: null,

    SlideInterval: 10,
    ExpandIncrement: 10,
    CollapseIncrement: 20,

    /**  REGISTER THE DIV TO EXPAND AND COLLAPSE  **/
    RegisterDiv: function(ownerId, targetId, minHeight, maxHeight, minWidth, maxWidth, type, expanded) {
        var divInfo = new Array();

        divInfo[ID] = targetId;
        divInfo[OBJECT] = $get(targetId);
        divInfo[MIN_HEIGHT] = minHeight;
        divInfo[MAX_HEIGHT] = maxHeight;
        divInfo[MIN_WIDTH] = minWidth;
        divInfo[MAX_WIDTH] = maxWidth;
        divInfo[EXPAND_TYPE] = type;
        divInfo[EXPANDED_FLAG] = expanded;

        this.DivArray[this.DivCount] = divInfo;

        this.DivCount++;
    },

    /**  HELPER FUNCTION TO GET THE ARRAY INDEX OF THE DIV WITH ID=targetId  **/
    DivIndex: function(targetId) {
        var i = 0;
        while (i < this.DivCount) {
            if (this.DivArray[i][ID] == targetId) {
                return i;
            }
            i++;
        }
        return null;
    },

    /**  INITIALISE THE DIVs  **/
    Init: function(interval, expandInc, collapseInc) {

        //  LOOP OVER THE DIVs THAT HAVE BEEN REGISTERED
        for (var i = 0; i < this.DivCount; i++) {

            //  SET THE STATE OF THE DIVs REGISTERED FOR VERTICAL EXPAND/COLLPASE
            if (this.DivArray[i][EXPAND_TYPE] == this.Vertical ||
                    this.DivArray[i][EXPAND_TYPE] == this.Both) {
                if (this.DivArray[i][EXPANDED_FLAG]) {
                    this.DivArray[i][OBJECT].style.height = this.DivArray[i][MAX_HEIGHT] + 'px';
                } else {
                    this.DivArray[i][OBJECT].style.height = this.DivArray[i][MIN_HEIGHT] + 'px';
                }
            }

            //  SET THE STATE OF THE DIVs REGISTERED FOR HORIZONTAL EXPAND/COLLPASE
            if (this.DivArray[i][EXPAND_TYPE] == this.Horizontal ||
                    this.DivArray[i][EXPAND_TYPE] == this.Both) {
                if (this.DivArray[i][EXPANDED_FLAG]) {
                    this.DivArray[i][OBJECT].style.width = this.DivArray[i][MAX_WIDTH] + 'px';
                } else {
                    this.DivArray[i][OBJECT].style.width = this.DivArray[i][MIN_WIDTH] + 'px';
                }
            }
        }

        //  SET ANY USER DEFINED INTERVAL AND INCREMENTS
        if (interval) this.SlideInterval = interval;
        if (expandInc) this.ExpandIncrement = expandInc;
        if (collapseInc) this.CollapseIncrement = collapseInc;

        return this;
    },

    /**  INITIALISE THE EXPANSION OF A DIV  **/
    /**  FOR EXAMPLE, ON A mouseover EVENT  **/
    Expand: function(targetId) {
        var newExpand = false;
        var cancelCollapse = false;

        //  MAKE SURE THAT THE NEW DIV IS NOT COLLAPSING
        for (var i = 0; i < this.DivCollapse.length; i++) {
            if (this.DivArray[this.DivCollapse[i]][ID] == targetId) {
                this.DivCollapse[i] = null;
                cancelCollapse = true;
            }
        }

        //  CLEAR ANT CANCELLED COLLAPSES FROM THE COLLAPSE ARRAY
        if (cancelCollapse) {
            var colCount = 0;
            var tmpArr = this.DivCollapse;
            this.DivCollapse = new Array();

            for (var i = 0; i < tmpArr.length; i++) {
                if (tmpArr[i] != null) {
                    this.DivCollapse[colCount] = tmpArr[i];
                    colCount++;
                }
            }
        }

        //  SET THE INDEX OF THE DIV TO BE EXPANDED
        //  ONLY ONE AT A TIME - SO FAR
        this.DivExpand = this.DivIndex(targetId);

        //  IF THE SLIDER ISN'T ALREADY RUNNING, START IT
        if (!this.SlideActive) {
            this.SlideActive = true;
            this.DoSlide();
        }
    },


    /**  CALLED IT INITIALISE THE COLLAPSE OF A DIV  **/
    /**  FOR EXAMPLE, ON A mouseout EVENT  **/
    Collapse: function(targetId, owner, evt) {
        var isChild = false;
        var collapseIndex = this.DivIndex(targetId);

        //  THERE MAY BE NESTED OBJECTS THAT CAN CAUSE A mouseout EVENT
        //  WE DON'T WANT TO RESPOND TO THESE EVENETS, SO, CHECK FOR A CHILD OBJECT
        if (!IsChildElement(owner, evt)) {
            this.DivCollapse[this.DivCollapse.length] = collapseIndex;

            if (collapseIndex == this.DivExpand) {
                this.DivExpand = null;
            }

            if (!this.SlideActive) {
                this.SlideActive = true;
                this.DoSlide();
            }
        }

    },


    /**  CARRIES OUT THE SLIDING PROCESS FOR EXPANDING AND COLLAPSING DIVS  **/
    DoSlide: function() {

        /**  **************  **/
        /**   START EXPAND   **/
        /**  **************  **/
        if (this.DivExpand != null) {
            var finishedHoriz = false;
            var finishedVert = false;
            var divObject = this.DivArray[this.DivExpand][OBJECT];

            //  EXPAND THE HEIGHT
            if (this.DivArray[this.DivExpand][EXPAND_TYPE] == this.Vertical ||
                    this.DivArray[this.DivExpand][EXPAND_TYPE] == this.Both) {
                divObject.style.height = parseInt(divObject.style.height) + this.ExpandIncrement + 'px';
            }

            //  EXPAND THE WIDTH
            if (this.DivArray[this.DivExpand][EXPAND_TYPE] == this.Horizontal ||
                    this.DivArray[this.DivExpand][EXPAND_TYPE] == this.Both) {
                divObject.style.width = parseInt(divObject.style.width) + this.ExpandIncrement + 'px';
            }

            //  CHECK THE VERTICAL SLIDE FOR MAX_HEIGHT
            if ((this.DivArray[this.DivExpand][EXPAND_TYPE] == this.Vertical ||
                    this.DivArray[this.DivExpand][EXPAND_TYPE] == this.Both) &&
                    parseInt(divObject.style.height) >= this.DivArray[this.DivExpand][MAX_HEIGHT]) {
                divObject.style.height = this.DivArray[this.DivExpand][MAX_HEIGHT] + 'px';
                finishedHoriz = true;
            } else if (this.DivArray[this.DivExpand][EXPAND_TYPE] != this.Vertical &&
                    this.DivArray[this.DivExpand][EXPAND_TYPE] != this.Both) {
                finishedHoriz = true;
            }

            //  CHECK THE HORIZONTAL SLIDE FOR MAX_WIDTH
            if ((this.DivArray[this.DivExpand][EXPAND_TYPE] == this.Horizontal ||
                    this.DivArray[this.DivExpand][EXPAND_TYPE] == this.Both) &&
                    parseInt(divObject.style.width) >= this.DivArray[this.DivExpand][MAX_WIDTH]) {
                divObject.style.width = this.DivArray[this.DivExpand][MAX_WIDTH] + 'px';
                finishedVert = true;
            } else if (this.DivArray[this.DivExpand][EXPAND_TYPE] != this.Horizontal &&
                    this.DivArray[this.DivExpand][EXPAND_TYPE] != this.Both) {
                finishedVert = true;
            }

            //  CHECK TO SEE IF WE HAVE COMPLETED THE EXPAND
            if (finishedHoriz && finishedVert) {
                this.DivExpand = null;
            }
        }    /**    END EXPAND    **/


        /**  **************  **/
        /**  START COLLAPSE  **/
        /**  **************  **/
        if (this.DivCollapse.length > 0) {
            var finishedCollapse = false;
            for (var i = 0; i < this.DivCollapse.length; i++) {
                var finishedHoriz = false;
                var finishedVert = false;
                var divObject = this.DivArray[this.DivCollapse[i]][OBJECT];

                //  COLLAPSE THE HEIGHT
                if (this.DivArray[this.DivCollapse[i]][EXPAND_TYPE] == this.Vertical ||
                        this.DivArray[this.DivCollapse[i]][EXPAND_TYPE] == this.Both) {
                    var newHeight = parseInt(divObject.style.height) - this.CollapseIncrement;

                    if (newHeight < 0) {
                        newHeight = 0;
                    }
                    divObject.style.height = newHeight + 'px';
                }

                //  COLLAPSE THE WIDTH
                if (this.DivArray[this.DivCollapse[i]][EXPAND_TYPE] == this.Horizontal ||
                        this.DivArray[this.DivCollapse[i]][EXPAND_TYPE] == this.Both) {
                    var newWidth = parseInt(divObject.style.width) - this.CollapseIncrement;

                    if (newWidth < 0) {
                        newWidth = 0;
                    }
                    divObject.style.width = newWidth + 'px';
                }


                //  CHECK THE VERTICAL COLLAPSE FOR MIN_HEIGHT
                if ((this.DivArray[this.DivCollapse[i]][EXPAND_TYPE] == this.Vertical ||
                        this.DivArray[this.DivCollapse[i]][EXPAND_TYPE] == this.Both) &&
                        parseInt(divObject.style.height) <= this.DivArray[this.DivCollapse[i]][MIN_HEIGHT]) {
                    divObject.style.height = this.DivArray[this.DivCollapse[i]][MIN_HEIGHT];
                    finishedHoriz = true;
                } else if (this.DivArray[this.DivCollapse[i]][EXPAND_TYPE] != this.Vertical &&
                        this.DivArray[this.DivCollapse[i]][EXPAND_TYPE] != this.Both) {
                    finishedHoriz = true;
                }

                //  CHECK THE HORIZONTAL COLLAPSE FOR MIN_WIDTH
                if ((this.DivArray[this.DivCollapse[i]][EXPAND_TYPE] == this.Horizontal ||
                        this.DivArray[this.DivCollapse[i]][EXPAND_TYPE] == this.Both) &&
                        parseInt(divObject.style.width) <= this.DivArray[this.DivCollapse[i]][MIN_WIDTH]) {
                    divObject.style.width = this.DivArray[this.DivCollapse[i]][MIN_WIDTH] + 'px';
                    finishedVert = true;
                } else if (this.DivArray[this.DivCollapse[i]][EXPAND_TYPE] != this.Horizontal &&
                        this.DivArray[this.DivCollapse[i]][EXPAND_TYPE] != this.Both) {
                    finishedVert = true;
                }

                //  CHECK TO SEE IF WE HAVE COMPLETED THE COLLAPSE
                if (finishedHoriz && finishedVert) {
                    this.DivCollapse[i] = null;
                    finishedCollapse = true;
                }
            }

            //  CLEAR ANY COMPLETED COLLAPSES FROM THE COLLAPSE ARRAY
            if (finishedCollapse) {
                var colCount = 0;
                var tmpArr = this.DivCollapse;
                this.DivCollapse = new Array();

                for (var i = 0; i < tmpArr.length; i++) {
                    if (tmpArr[i] != null) {
                        this.DivCollapse[colCount] = tmpArr[i];
                        colCount++;
                    }
                }
            }
        }    /**   END COLLAPSE   **/


        //  CHECK FOR ANY REMAINING EXPAND OR COLLAPSE OPERATIONS
        if (this.DivCollapse.length > 0 || this.DivExpand != null) {

            //  STILL NEED TO SLIDE
            var self = this;
            this.SlideProcess = setTimeout(function() { self.DoSlide(); }, this.SlideInterval);
        } else {

            //  ALL SLIDING HAS FINISHED
            this.SlideActive = false;
        }
    }
}
