﻿﻿// ***********************************************************************************************************
// Name: Named List
// Type: Object
// Author: Cliff Gower
//************************************************************************************************************

var Framework = Framework || {};
Framework.Collections = Framework.Collections || {};

Framework.Collections.NamedList = function() {
    this.KeyValuePairs = new Object();
    this.KeyValuePairIterator = new Array();
}

Framework.Collections.NamedList.prototype.Add = function (key, value) {
    this.KeyValuePairs[key] = value;
    this.KeyValuePairIterator.push(key);
};

Framework.Collections.NamedList.prototype.Remove = function (key) {
    var index = this.FindItemIndex(key);
    this.RemoveItemAt(index);
};

Framework.Collections.NamedList.prototype.RemoveItemAt = function (index) {
    if (this.KeyValuePairIterator[index] != null
    && this.KeyValuePairIterator[index] != undefined) {
        var key = this.KeyValuePairIterator[index];
        delete this.KeyValuePairs[key];
        this.KeyValuePairIterator.splice(index, 1);
    }
};

Framework.Collections.NamedList.prototype.Clear = function () {
    var listSize = this.KeyValuePairIterator.length;
    this.KeyValuePairs.splice(0, listSize);
    this.KeyValuePairIterator.splice(0, listSize);
};

Framework.Collections.NamedList.prototype.Item = function (key) {
    if (this.KeyValuePairs[key] != null
    && this.KeyValuePairs[key] != undefined) {
        return this.KeyValuePairs[key];
    }
};

Framework.Collections.NamedList.prototype.ItemAt = function (index) {
    if (this.KeyValuePairIterator[index] != null
    && this.KeyValuePairIterator[index] != undefined) {
        var key = this.KeyValuePairIterator[index];
        return this.KeyValuePairs[key];
    }
};

Framework.Collections.NamedList.prototype.Count = function () {
    return this.KeyValuePairIterator.length;
};

Framework.Collections.NamedList.prototype.FindItemIndex = function (key) {
    for (index = 0; index < this.KeyValuePairIterator.length; index++) {
        if (this.KeyValuePairIterator[index] == key) {
            return index;
        }
    }

    return -1;
};




﻿// ***********************************************************************************************************
// Name: Custom Event Handling Base Class
// Type: Base Class
// Author: Cliff Gower
//************************************************************************************************************

//dependencies
//Framework.Collections.NamedList.js

var Framework = Framework || {};

Framework.CustomEventHandlingBase = function () {
    this.Events = new Framework.Collections.NamedList();
}

Framework.CustomEventHandlingBase.prototype.AddEvent = function (event) {
    var eventHandlerList = new Framework.Collections.NamedList();
    this.Events.Add(event, eventHandlerList);
};

Framework.CustomEventHandlingBase.prototype.RemoveEvent = function (event) {
    this.Events.Remove(event);
};

Framework.CustomEventHandlingBase.prototype.RegisterEventHandler = function (eventHandler) {
    if (this.Events.Item(eventHandler.Event) == null || this.Events.Item(eventHandler.Event) == undefined) {
        this.AddEvent(eventHandler.Event);
    }

    this.Events.Item(eventHandler.Event).Add(eventHandler.Name, eventHandler);
};

Framework.CustomEventHandlingBase.prototype.UnregisterEventHandler = function (eventHandlerName, event) {
    this.Events.Item(event).Remove(eventHandlerName);
};

Framework.CustomEventHandlingBase.prototype.FireEvent = function (event, eventArgs) {
    var eventToFire = this.Events.Item(event);
    for (var index = 0; index < eventToFire.Count(); index++) {
        eventToFire.ItemAt(index).Delegate(eventArgs);
    }
};


Framework.CustomEventHandler = function (name, event, delegate) {
    this.Name = null;
    this.Event = null;
    this.Delegate = null;

    if (name != null && name != undefined) {
        this.Name = name;
    }

    if (event != null && event != undefined) {
        this.Event = event;
    }

    if (delegate != null && delegate != undefined) {
        this.Delegate = delegate;
    }
}

﻿var Framework = Framework || {};

//*********************** Event Handler Creation ***************************
Framework.AddHandler = function (object, eventName, handler) {
    if (object.addEventListener) { object.addEventListener(eventName, handler, false); }
    else { object.attachEvent("on" + eventName, handler); }
};

Framework.RemoveHandler = function (object, eventName, handler) {
    if (object.removeEventListener) { object.removeEventListener(eventName, handler, false); }
    else { object.detachEvent("on" + eventName, handler); }
};

Framework.AddWheelHandler = function (handler) {
    if (document.addEventListener) {
        document.addEventListener('DOMMouseScroll', handler, false);
        document.addEventListener('mousewheel', handler, false); 
    }
    else {
        document.attachEvent("onmousewheel", handler); 
    }
};

Framework.RemoveWheelHandler = function (handler) {
    if (document.removeEventListener) {
        document.removeEventListener('DOMMouseScroll', handler, false);
        document.removeEventListener('mousewheel', handler, false);
    }
    else {
        document.detachEvent("onmousewheel", handler); 
    }
};

Framework.CreateDelegate = function (object, method) {
    return (function () { return method.apply(object, arguments); })
};



﻿// ***********************************************************************************************************
// Name: Animation Library
// Type: Library
// Author: Cliff Gower
//************************************************************************************************************

var Framework = Framework || {};
Framework.Animation = Framework.Animation || {};

//dependencies
//Framework.EventHandling.js

Framework.Animation.AccelerationType = {
    ZERO: '(elapsedTime * (1 / duration))',
    SINUSOIDAL: 'Math.abs(Math.sin(elapsedTime * (Math.PI / (2 * duration))))',
    EASE_IN: 'Math.pow(((1 /duration) * elapsedTime), 1.25)',
    EASE_OUT: 'Math.pow(((1 /duration) * elapsedTime), .25)',
    QUADRATIC_EASE_IN: '(elapsedTime /= duration) * elapsedTime',
    QUADRATIC_EASE_OUT: '-((elapsedTime /= duration) * (elapsedTime -2))',
    CUBIC_EASE_IN: '(elapsedTime /= duration) * elapsedTime * elapsedTime',
    CUBIC_EASE_OUT: '(( elapsedTime = elapsedTime/duration - 1) * elapsedTime * elapsedTime + 1)',
    QUARTIC_EASE_IN: '(elapsedTime /= duration)* elapsedTime * elapsedTime * elapsedTime',
    QUARTIC_EASE_OUT: '-((elapsedTime = elapsedTime/duration - 1) * elapsedTime * elapsedTime * elapsedTime - 1)',
    QUINTIC_EASE_IN: '(elapsedTime /= duration) * elapsedTime * elapsedTime * elapsedTime * elapsedTime',
    QUINTIC_EASE_OUT: '((elapsedTime = elapsedTime/duration - 1) * elapsedTime * elapsedTime * elapsedTime * elapsedTime + 1)',
    SINUSOIDAL_EASE_IN: '-(Math.cos(elapsedTime/duration * (Math.PI/2)) + c)',
    SINUSOIDAL_EASE_OUT: 'Math.sin(elapsedTime/duration * (Math.PI/2))',
    CIRCULAR_EASE_IN: '-(Math.sqrt(1 - (elapsedTime /= duration) * elapsedTime) - 1)',
    CIRCULAR_EASE_OUT: 'Math.sqrt(1 - (elapsedTime = elapsedTime / duration - 1) * elapsedTime)',
    BACK_EASE_IN: '(elapsedTime /= duration) * elapsedTime * ((1.70158 + 1) * elapsedTime - 1.70158)',
    BACK_EASE_OUT: '((elapsedTime = elapsedTime / duration - 1) * elapsedTime * ((1.70158 + 1) * elapsedTime + 1.70158) + 1)',
    COSINE: 'Math.cos(elapsedTime * (Math.PI / (2 * 300)))',
    SINE: 'Math.sin(elapsedTime * (Math.PI / (2 * 300)))',
    TANGENT: 'Math.tan(elapsedTime * (Math.PI / (2 * 300)))'
};


Framework.Animation.Dimension = function (width, height) {
    this.Width = null;
    this.Height = null;

    if (width != null && width != undefined) { this.Width = width; }
    if (height != null && height != undefined) { this.Height = height; }
}


Framework.Animation.Coordinate = function (posX, posY) {
    this.PositionX = null;
    this.PositionY = null;

    if (posX != null && posX != undefined) { this.PositionX = posX; }
    if (posY != null && posY != undefined) { this.PositionY = posY; }
}

Framework.Animation.RGB = function (r, g, b) {
    this.Red = r;
    this.Green = g;
    this.Blue = b;
}

Framework.Animation.Color = function () {
    this.m_Web = null;
    this.m_RGB = null;
};

Framework.Animation.Color.prototype.Web = function (hexValue) {
    if (hexValue != null && hexValue != undefined) {
        this.m_Web = hexValue;
        this.m_RGB = Framework.Animation.ConvertHexColorToRgb(hexValue);
    }

    return this.m_Web;
}

Framework.Animation.Color.prototype.RGB = function (rgb) {
    if (rgb != null && rgb != undefined) {
        this.m_RGB = rgb;
        this.m_Web = Framework.Animation.ConvertRgbToHexColor(this.m_RGB);
    }

    return this.m_RGB;
}

Framework.Animation.GetOpacity = function (element) {
    var opacity = 100;
    if (document.attachEvent && element.currentStyle.filter) {
        var opacityString = element.currentStyle.filter;
        var matches = opacityString.match(/alpha\(opacity=(\d+)\)/);
        if (matches.length > 0) {
            opacity = (matches[1] / 10);
        }
        else {
            opacity = opacity / 10;
        }
    }
    else {
       opacity = (element.style.opacity * 10);
   }

   return opacity;

}

Framework.Animation.GetColor = function (element) {
    var color = new Framework.Animation.Color();
    if (document.attachEvent && element.currentStyle.backgroundColor) {
        color.Web(element.currentStyle.backgroundColor);
    }
    else {
        color.Web(element.style.backgroundColor);
    }

    return color;
}

Framework.Animation.HexToDecimalMap = {
    "0": 0,
    "1": 1,
    "2": 2,
    "3": 3,
    "4": 4,
    "5": 5,
    "6": 6,
    "7": 7,
    "8": 8,
    "9": 9,
    "A": 10,
    "B": 11,
    "C": 12,
    "D": 13,
    "E": 14,
    "F": 15
};

Framework.Animation.ConvertHexColorToRgb = function (hexValue) {
    var redHex = hexValue.substr(1, 2);
    var redRgb = Framework.Animation.ConvertHexColorComponentToRgbComponent(redHex);

    var greenHex = hexValue.substr(3, 2);
    var greenRgb = Framework.Animation.ConvertHexColorComponentToRgbComponent(greenHex);

    var blueHex = hexValue.substr(5, 2);
    var blueRgb = Framework.Animation.ConvertHexColorComponentToRgbComponent(blueHex);

    return new Framework.Animation.RGB(redRgb, greenRgb, blueRgb);
};

Framework.Animation.ConvertHexColorComponentToRgbComponent = function (hexColorComponent) {
    var hex1 = Framework.Animation.HexToDecimalMap[hexColorComponent.substr(0, 1).toUpperCase()];
    var hex2 = Framework.Animation.HexToDecimalMap[hexColorComponent.substr(1, 1).toUpperCase()];
    var rgb = hex1 * 16 + hex2;

    return rgb;
};

Framework.Animation.ConvertRgbToHexColor = function (rgb) {
    var hexColor = '#';
    hexColor = hexColor + Framework.Animation.ConvertRgbComponentToHex(rgb.Red);
    hexColor = hexColor + Framework.Animation.ConvertRgbComponentToHex(rgb.Green);
    hexColor = hexColor + Framework.Animation.ConvertRgbComponentToHex(rgb.Blue);

    return hexColor;
};

Framework.Animation.ConvertRgbComponentToHex = function (rgbValue) {
    var nybHexString = "0123456789ABCDEF";
    var hexValue = String(nybHexString.substr((rgbValue >> 4) & 0x0F, 1)) + nybHexString.substr(rgbValue & 0x0F, 1);
    return hexValue;
};




﻿// ***********************************************************************************************************
// Name: Animations Library
// Type:User Library
// Author: Cliff Gower
//************************************************************************************************************

var Framework = Framework || {};
Framework.Animation = Framework.Animation || {};

//***********************  Animation Abstract Class ***************************
Framework.Animation.AnimationBase = function () {
    this.m_Element = null;
    this.m_Duration = null;
    this.m_Interval = null;
    this.m_AccelerationType = null;
    this.m_StartTime = null;
    this.m_Timer = null;

    this.OnAnimationStart = null;
    this.OnAnimationComplete = null;
}

Framework.Animation.AnimationBase.prototype.TimerIntervalHandler = function () {
    var elapsedTime = (this.m_StartTime += this.m_Interval);

    var percentChange = this.GetPercentChange(elapsedTime);
    this.Animate(percentChange);

    if (elapsedTime >= this.m_Duration) {
        this.Stop();
        this.AnimationComplete();
    }
}

Framework.Animation.AnimationBase.prototype.InitBase = function (element, duration, interval, acceleration) {
    this.m_Element = element;
    this.m_Duration = duration;
    this.m_Interval = interval;
    this.m_AccelerationType = acceleration;
}

Framework.Animation.AnimationBase.prototype.Start = function () {
    if (this.OnAnimationStart != null) {
        this.OnAnimationStart();
    }

    this.InitAnimation();

    this.m_StartTime = 0;
    this.m_Timer = setInterval(Framework.CreateDelegate(this, this.TimerIntervalHandler), this.m_Interval);
}

Framework.Animation.AnimationBase.prototype.Stop = function () {
    clearInterval(this.m_Timer);
}

Framework.Animation.AnimationBase.prototype.InitAnimation = function () { }

Framework.Animation.AnimationBase.prototype.Animate = function (percentChange) { }

Framework.Animation.AnimationBase.prototype.AnimationComplete = function () {
    if (this.OnAnimationComplete != null) {
        this.OnAnimationComplete();
    }
}

Framework.Animation.AnimationBase.prototype.GetPercentChange = function (elapsedTime) {
    var duration = this.m_Duration;

    var change = eval(this.m_AccelerationType)
    return change;
}





//*********************** Resize Animation ***************************
Framework.Animation.ResizeAnimation = function (element, endWidth, endHeight, duration, interval, acceleration) {
    this.m_StartWidth = null;
    this.m_StartHeight = null;
    this.m_EndWidth = endWidth;
    this.m_EndHeight = endHeight;

    this.m_ChangeWidth = null;
    this.m_ChangeHeight = null;

    this.InitBase(element, duration, interval, acceleration);
}

Framework.Animation.ResizeAnimation.prototype = new Framework.Animation.AnimationBase();

Framework.Animation.ResizeAnimation.prototype.InitAnimation = function () {
    this.m_StartWidth = this.m_Element.clientWidth;
    this.m_StartHeight = this.m_Element.clientHeight;

    this.m_ChangeWidth = this.m_EndWidth - this.m_StartWidth;
    this.m_ChangeHeight = this.m_EndHeight - this.m_StartHeight;
}

Framework.Animation.ResizeAnimation.prototype.Animate = function (percentChange) {
    this.m_Element.style.height = Math.abs(Math.round(this.m_StartHeight + (percentChange * this.m_ChangeHeight))) + 'px';
    this.m_Element.style.width = Math.abs(Math.round(this.m_StartWidth + (percentChange * this.m_ChangeWidth))) + 'px';
}




//*********************** Move Animation ***************************
Framework.Animation.MoveAnimation = function (element, endPosX, endPosY, duration, interval, acceleration) {
    this.m_StartPosX = null;
    this.m_StartPosY = null;
    this.m_EndPosX = endPosX;
    this.m_EndPosY = endPosY;

    this.m_ChangeInPosX = null;
    this.m_ChangeInPosY = null;

    this.InitBase(element, duration, interval, acceleration);
}

Framework.Animation.MoveAnimation.prototype = new Framework.Animation.AnimationBase();

Framework.Animation.MoveAnimation.prototype.InitAnimation = function () {
    this.m_StartPosX = this.m_Element.offsetLeft;
    this.m_StartPosY = this.m_Element.offsetTop;

    this.m_ChangeInPosX = this.m_EndPosX - this.m_StartPosX;
    this.m_ChangeInPosY = this.m_EndPosY - this.m_StartPosY;
}

Framework.Animation.MoveAnimation.prototype.Animate = function (percentChange) {
    this.m_Element.style.left = Math.round(this.m_StartPosX + (percentChange * this.m_ChangeInPosX)) + 'px';
    this.m_Element.style.top = Math.round(this.m_StartPosY + (percentChange * this.m_ChangeInPosY)) + 'px';
}


//*********************** Move By Animation ***************************
Framework.Animation.MoveByAnimation = function (element, changeInPosX, changeInPosY, duration, interval, acceleration) {
    this.m_StartPosX = null;
    this.m_StartPosY = null;
    this.m_ChangeInPosX = changeInPosX;
    this.m_ChangeInPosY = changeInPosY;

    this.InitBase(element, duration, interval, acceleration);
}

Framework.Animation.MoveAnimation.prototype = new Framework.Animation.AnimationBase();

Framework.Animation.MoveAnimation.prototype.InitAnimation = function () {
    this.m_StartPosX = this.m_Element.offsetLeft;
    this.m_StartPosY = this.m_Element.offsetTop;
}

Framework.Animation.MoveAnimation.prototype.Animate = function (percentChange) {
    this.m_Element.style.left = Math.round(this.m_StartPosX + (percentChange * this.m_ChangeInPosX)) + 'px';
    this.m_Element.style.top = Math.round(this.m_StartPosY + (percentChange * this.m_ChangeInPosY)) + 'px';
}



//*********************** Horizontal Move Animation ***************************
Framework.Animation.HorizontalMoveAnimation = function (element, endPosX, duration, interval, acceleration) {
    this.m_StartPosX = null;
    this.m_EndPosX = endPosX;

    this.InitBase(element, duration, interval, acceleration);
}

Framework.Animation.HorizontalMoveAnimation.prototype = new Framework.Animation.AnimationBase();

Framework.Animation.HorizontalMoveAnimation.prototype.InitAnimation = function () {
    this.m_StartPosX = this.m_Element.offsetLeft;
    this.m_ChangeInPosX = this.m_EndPosX - this.m_StartPosX;
}

Framework.Animation.HorizontalMoveAnimation.prototype.Animate = function (percentChange) {
    this.m_Element.style.left = Math.round(this.m_StartPosX + (percentChange * this.m_ChangeInPosX)) + 'px';
}



//*********************** Horizontal Move By Animation ***************************
Framework.Animation.HorizontalMoveByAnimation = function (element, changeInPosX, duration, interval, acceleration) {
    this.m_StartPosX = null;
    this.m_ChangeInPosX = changeInPosX;

    this.InitBase(element, duration, interval, acceleration);
}

Framework.Animation.HorizontalMoveByAnimation.prototype = new Framework.Animation.AnimationBase();

Framework.Animation.HorizontalMoveByAnimation.prototype.InitAnimation = function () {
    this.m_StartPosX = this.m_Element.offsetLeft;
}

Framework.Animation.HorizontalMoveByAnimation.prototype.Animate = function (percentChange) {
    this.m_Element.style.left = Math.round(this.m_StartPosX + (percentChange * this.m_ChangeInPosX)) + 'px';
}



//*********************** Vertical Move Animation ***************************
Framework.Animation.VerticalMoveAnimation = function (element, endPosY, duration, interval, acceleration) {
    this.m_StartPosY = null
    this.m_EndPosY = endPosY;
    this.m_ChangeInPosY = null;

    this.InitBase(element, duration, interval, acceleration);
}

Framework.Animation.VerticalMoveAnimation.prototype = new Framework.Animation.AnimationBase();

Framework.Animation.VerticalMoveAnimation.prototype.InitAnimation = function () {
    this.m_StartPosY = this.m_Element.offsetTop;
    this.m_ChangeInPosY = this.m_EndPosY - this.m_StartPosY;
}

Framework.Animation.VerticalMoveAnimation.prototype.Animate = function (percentChange) {
    this.m_Element.style.top = Math.round(this.m_StartPosY + (percentChange * this.m_ChangeInPosY)) + 'px';
}



//*********************** Vertical Move Animation ***************************
Framework.Animation.VerticalMoveByAnimation = function (element, changeInPosY, duration, interval, acceleration) {
    this.m_StartPosY = null
    this.m_ChangeInPosY = changeInPosY;

    this.InitBase(element, duration, interval, acceleration);
}

Framework.Animation.VerticalMoveByAnimation.prototype = new Framework.Animation.AnimationBase();

Framework.Animation.VerticalMoveByAnimation.prototype.InitAnimation = function () {
    this.m_StartPosY = this.m_Element.offsetTop;
}

Framework.Animation.VerticalMoveByAnimation.prototype.Animate = function (percentChange) {
    this.m_Element.style.top = Math.round(this.m_StartPosY + (percentChange * this.m_ChangeInPosY)) + 'px';
}



//*********************** Opacity Animation ***************************
Framework.Animation.OpacityAnimation = function (element, endOpacity, duration, interval, acceleration) {
    this.m_StartOpacity = null;
    this.m_EndOpacity = endOpacity;
    this.m_ChangeOpacity = null;

    this.InitBase(element, duration, interval, acceleration);
}

Framework.Animation.OpacityAnimation.prototype = new Framework.Animation.AnimationBase();

Framework.Animation.OpacityAnimation.prototype.InitAnimation = function () {
    this.m_StartOpacity = Framework.Animation.GetOpacity(this.m_Element);
    this.m_ChangeOpacity = this.m_EndOpacity - this.m_StartOpacity;
}

Framework.Animation.OpacityAnimation.prototype.Animate = function (percentChange) {
    var newOpacity = Math.round(this.m_StartOpacity + (percentChange * this.m_ChangeOpacity));
    this.m_Element.style.filter = 'alpha(opacity=' + (newOpacity * 10) + ')';
    this.m_Element.style.opacity = newOpacity / 10;
}




//*********************** Color Animation ***************************
Framework.Animation.ColorAnimation = function (element, endColor, duration, interval, acceleration) {
    this.m_StartColor = null;
    this.m_EndColor = endColor;
    this.m_ChangeColor = new Framework.Animation.RGB(null, null, null);

    this.InitBase(element, duration, interval, acceleration);
}

Framework.Animation.ColorAnimation.prototype = new Framework.Animation.AnimationBase();

Framework.Animation.ColorAnimation.prototype.InitAnimation = function () {
    this.m_StartColor = Framework.Animation.GetColor(this.m_Element);
    this.m_ChangeColor.Red = this.m_EndColor.RGB().Red - this.m_StartColor.RGB().Red;
    this.m_ChangeColor.Green = this.m_EndColor.RGB().Green - this.m_StartColor.RGB().Green;
    this.m_ChangeColor.Blue = this.m_EndColor.RGB().Blue - this.m_StartColor.RGB().Blue;
}

Framework.Animation.ColorAnimation.prototype.Animate = function (percentChange) {
    var newColorRgb = new Framework.Animation.RGB(null, null, null);
    newColorRgb.Red = Math.round(this.m_StartColor.RGB().Red + (percentChange * this.m_ChangeColor.Red));
    newColorRgb.Green = Math.round(this.m_StartColor.RGB().Green + (percentChange * this.m_ChangeColor.Green));
    newColorRgb.Blue = Math.round(this.m_StartColor.RGB().Blue + (percentChange * this.m_ChangeColor.Blue));

    var newColor = new Framework.Animation.Color();
    newColor.RGB(newColorRgb);

    this.m_Element.style.backgroundColor = newColor.Web();
}


﻿// ***********************************************************************************************************
// Name:Control Objects
// Type:User Control
// Author: Cliff Gower
//************************************************************************************************************

var Framework = Framework || {};
Framework.Controls = Framework.Controls || {};


Framework.Controls.Trigger = function (triggerElement, triggerType) {
    this.TriggerElement = triggerElement;
    this.TriggerType = triggerType;

    this.OnTriggerMouseOver = null;
    this.OnTriggerMouseOut = null;
    this.OnTriggerClick = null;
    this.OnTriggerClickWithEventArgs = null;

    Framework.AddHandler(this.TriggerElement, 'click', Framework.CreateDelegate(this, this.TriggerElementClickHandler));
    Framework.AddHandler(this.TriggerElement, 'click', Framework.CreateDelegate(this, this.TriggerElementClickWithEventArgsHandler));

    Framework.AddHandler(this.TriggerElement, 'mouseover', Framework.CreateDelegate(this, this.TriggerElementMouseOverHandler));
    Framework.AddHandler(this.TriggerElement, 'mouseout', Framework.CreateDelegate(this, this.TriggerElementMouseOutHandler));
};

Framework.Controls.Trigger.prototype.TriggerElementMouseOverHandler = function () {
    if (this.OnTriggerMouseOver != null && this.OnTriggerMouseOver != undefined) {
        this.OnTriggerMouseOver(this.TriggerType);
    }
};

Framework.Controls.Trigger.prototype.TriggerElementMouseOutHandler = function () {
    if (this.OnTriggerMouseOut != null && this.OnTriggerMouseOut != undefined) {
        this.OnTriggerMouseOut(this.TriggerType);
    }
};

Framework.Controls.Trigger.prototype.TriggerElementClickHandler = function () {
    if (this.OnTriggerClick != null && this.OnTriggerClick != undefined) {
        this.OnTriggerClick(this.TriggerType);
    }
};

Framework.Controls.Trigger.prototype.TriggerElementClickWithEventArgsHandler = function (e) {
    if (this.OnTriggerClickWithEventArgs != null && this.OnTriggerClickWithEventArgs != undefined) {
        this.OnTriggerClickWithEventArgs(e);
    }
};


Framework.Controls.Coordinate = function (posX, posY) {
    this.PositionX = null;
    this.PositionY = null;

    if (posX != null && posX != undefined) { this.PositionX = posX; }
    if (posY != null && posY != undefined) { this.PositionY = posY; }
}



﻿// ***********************************************************************************************************
// Name: Modal Panel
// Type: User Control
// Author: Cliff Gower
//************************************************************************************************************


//Dependencies
//Framework.Animation.js
//Framework.Animation.Animations.js
//Framework.Controls.js
//Framework.EventHandling.js


var Framework = Framework || {};
Framework.Controls = Framework.Controls || {};

Framework.Controls.ModalDisplayState = {
    SHOW: 0,
    HIDE: 1
}

Framework.Controls.ModalTriggerType = {
    SHOW: 0,
    HIDE: 1
}

Framework.Controls.ModalDisplayType = {
    SHOW: "block",
    HIDE: "none"
}

Framework.Controls.ModalPositionCenterSetting = {
    YES: true,
    NO: false
}

Framework.Controls.ModalAnimationSetting = {
    YES: true,
    NO: false
}

//*********************** modal panel object  ***************************
Framework.Controls.Modal = function (overlay, modal, center, animate) {
    this.m_Overlay = overlay;
    this.m_Modal = modal;
    this.m_Center = center;
    this.m_Animate = animate;

    this.m_OverlayFadeInAnimation = new Framework.Animation.OpacityAnimation(this.m_Overlay, 5, 500, 10, Framework.Animation.AccelerationType.CUBIC_EASE_OUT);
    this.m_OverlayFadeOutAnimation = new Framework.Animation.OpacityAnimation(this.m_Overlay, 0, 500, 10, Framework.Animation.AccelerationType.CUBIC_EASE_OUT);

    this.m_ModalFadeInAnimation = new Framework.Animation.OpacityAnimation(this.m_Modal, 10, 500, 10, Framework.Animation.AccelerationType.CUBIC_EASE_OUT);
    this.m_ModalFadeOutAnimation = new Framework.Animation.OpacityAnimation(this.m_Modal, 0, 500, 10, Framework.Animation.AccelerationType.CUBIC_EASE_OUT);

    //    if (/MSIE (5\.5|6)/.test(navigator.userAgent) || typeof filters == 'unknown') {
    //        this.m_Overlay.className = 'gm-ventures-modal-overlay-ie6';
    //    }

    this.OnShowModal = null;
    this.OnHideModal = null;
};

Framework.Controls.Modal.prototype.AddTrigger = function (trigger) {
    trigger.OnTriggerClick = Framework.CreateDelegate(this, this.TriggerClickHandler);
};

Framework.Controls.Modal.prototype.TriggerClickHandler = function (triggerType) {
    if (triggerType == Framework.Controls.ModalTriggerType.SHOW) { this.Show(); }
    if (triggerType == Framework.Controls.ModalTriggerType.HIDE) { this.Hide(); }
};

Framework.Controls.Modal.prototype.Show = function () {
    this.ToggleDisplay(Framework.Controls.ModalDisplayType.SHOW);

    if (this.m_Center) {
        this.CenterModal();
    }

    if (this.m_Animate) {
        this.AnimateShow();
    }

    if (this.OnShowModal != null) {
        this.OnShowModal();
    }
};

Framework.Controls.Modal.prototype.Hide = function () {
    alert('1');
    if (this.m_Animate) {
        this.AnimateHide();
    }
    else {
        this.ToggleDisplay(Framework.Controls.ModalDisplayType.HIDE);
    }

    alert('2');

    if (this.OnHideModal != null) {
        this.OnHideModal();
    }

    alert('3');
};

Framework.Controls.Modal.prototype.AnimateShow = function () {
    if (this.m_Overlay != null) {
        this.m_Overlay.style.filter = 'alpha(opacity=0)';
        this.m_Overlay.style.opacity = 0;
        this.m_OverlayFadeInAnimation.Start();
    }

    this.m_Modal.style.filter = 'alpha(opacity=0)';
    this.m_Modal.style.opacity = 0;
    this.m_ModalFadeInAnimation.Start();
};

Framework.Controls.Modal.prototype.AnimateHide = function () {
    alert('hiding');
    if (this.m_Overlay != null) {
        this.m_OverlayFadeOutAnimation.Start();
    }

    alert('hide');

    this.m_ModalFadeOutAnimation.Start();
    this.m_ModalFadeOutAnimation.OnAnimationComplete = Framework.CreateDelegate(this, this.HideAnimationCompletionHandler);
};

Framework.Controls.Modal.prototype.HideAnimationCompletionHandler = function () {
    this.ToggleDisplay(Framework.Controls.ModalDisplayType.HIDE);
};

Framework.Controls.Modal.prototype.ToggleDisplay = function (displayType) {
    if (this.m_Overlay != null) {
        this.m_Overlay.style.display = displayType;
    }

    this.m_Modal.style.display = displayType;
};

Framework.Controls.Modal.prototype.CenterModal = function () {
    var windowWidth = document.documentElement.clientWidth;
    var windowHeight = document.documentElement.clientHeight;

    var modalWidth = this.m_Modal.clientWidth;
    var modalHeight = this.m_Modal.clientHeight;

    var newTop = 10;
    if (modalHeight < windowHeight) { newTop = document.documentElement.scrollTop + ((windowHeight - modalHeight) / 2); }

    this.m_Modal.style.left = (windowWidth / 2 - modalWidth / 2) + 'px';
    this.m_Modal.style.top = newTop + 'px';

    if (this.OnShowModal != null) {
        this.OnShowModal();
    }
};

Framework.Controls.Modal.prototype.Hide = function () {
    if (this.m_Animate) {

        this.m_OverlayFadeOutAnimation.Start();
        this.m_ModalFadeOutAnimation.Start();

        this.m_ModalFadeOutAnimation.OnAnimationComplete = Framework.CreateDelegate(this, this.HideAnimationCompletionHandler);
    }
    else {
        this.ToggleDisplay(Framework.Controls.ModalDisplayType.HIDE);
    }

    if (this.OnHideModal != null) {
        this.OnHideModal();
    }
};

Framework.Controls.Modal.prototype.HideAnimationCompletionHandler = function () {
    this.ToggleDisplay(Framework.Controls.ModalDisplayType.HIDE);
};

Framework.Controls.Modal.prototype.ToggleDisplay = function (displayType) {
    if (this.m_Overlay != null) {
        this.m_Overlay.style.display = displayType;
    }

    this.m_Modal.style.display = displayType;
};

Framework.Controls.Modal.prototype.CenterModal = function () {
    var windowWidth = document.documentElement.clientWidth;
    var windowHeight = document.documentElement.clientHeight;

    var modalWidth = this.m_Modal.clientWidth;
    var modalHeight = this.m_Modal.clientHeight;

    var newTop = 10;
    if (modalHeight < windowHeight) { newTop = document.documentElement.scrollTop + ((windowHeight - modalHeight) / 2); }

    this.m_Modal.style.left = (windowWidth / 2 - modalWidth / 2) + 'px';
    this.m_Modal.style.top = newTop + 'px';
};


// ***********************************************************************************************************
// Name: Button Control
// Type:User Control
// Author: Cliff Gower
//************************************************************************************************************

var Framework = Framework || {};
Framework.Controls = Framework.Controls || {};

//dependencies
//Framework.EventHandling.js

Framework.Controls.ButtonEnabled = {
    YES: true,
    NO: false
}

Framework.Controls.ButtonControl = function (buttonElement) {
    this.ButtonElement = buttonElement;
    this.ButtonArgument = null;
    this.ButtonEnabled = Framework.Controls.ButtonEnabled.NO

    this.OnButtonClick = null;
    this.OnButtonMouseOver = null;
    this.OnButtonMouseOut = null;
    this.OnButtonEnable = null;
    this.OnButtonDisable = null;

    this.ButtonClickDelegate = Framework.CreateDelegate(this, this.ClickHandler);
    this.ButtonMouseOverDelegate = Framework.CreateDelegate(this, this.MouseOverHandler);
    this.ButtonMouseOutDelegate = Framework.CreateDelegate(this, this.MouseOutHandler);

    this.Enable();
};

Framework.Controls.ButtonControl.prototype.ClickHandler = function () {
    if (this.OnButtonClick != null) {
        this.OnButtonClick(this);
    }
};

Framework.Controls.ButtonControl.prototype.MouseOverHandler = function () {
    if (this.OnButtonMouseOver != null) {
        this.OnButtonMouseOver(this);
    }
};

Framework.Controls.ButtonControl.prototype.MouseOutHandler = function () {
    if (this.OnButtonMouseOut != null) {
        this.OnButtonMouseOut(this);
    }
};

Framework.Controls.ButtonControl.prototype.Enable = function () {
    if (this.ButtonEnabled == Framework.Controls.ButtonEnabled.YES) { return; }

    this.ButtonEnabled = Framework.Controls.ButtonEnabled.YES

    Framework.AddHandler(this.ButtonElement, 'click', this.ButtonClickDelegate);
    Framework.AddHandler(this.ButtonElement, 'mouseover', this.ButtonMouseOverDelegate);
    Framework.AddHandler(this.ButtonElement, 'mouseout', this.ButtonMouseOutDelegate);

    if (this.OnButtonEnable != null) {
        this.OnButtonEnable(this);
    }
};

Framework.Controls.ButtonControl.prototype.Disable = function () {
    if (this.ButtonEnabled == Framework.Controls.ButtonEnabled.NO) { return; }

    this.ButtonEnabled = Framework.Controls.ButtonEnabled.NO

    Framework.RemoveHandler(this.ButtonElement, 'click', this.ButtonClickDelegate);
    Framework.RemoveHandler(this.ButtonElement, 'mouseover', this.ButtonMouseOverDelegate);
    Framework.RemoveHandler(this.ButtonElement, 'mouseout', this.ButtonMouseOutDelegate);

    if (this.OnButtonDisable != null) {
        this.OnButtonDisable(this);
    }
};


// ***********************************************************************************************************
// Name:Collapsible Panel
// Type:User Control
// Author: Cliff Gower
//************************************************************************************************************

//dependencies
//Framework.Animation.js
//Framework.Animation.Animations.js
//Framework.Controls.js
//Framework.EventHandling.js

var Framework = Framework || {};
Framework.Controls = Framework.Controls || {};

Framework.Controls.CollapsiblePanelTriggerType = {
    'EXPAND': 0,
    'COLLAPSE': 1,
    'BOTH': 2,
    'NONE': 3
};

Framework.Controls.CollapsiblePanelState = {
    'EXPANDED': 0,
    'COLLAPSED': 1,
    'ANIMATING': 2
};

Framework.Controls.CollapsiblePanelStartState = {
    EXPANDED: true,
    COLLAPSED: false
};

Framework.Controls.CollapsiblePanelExpansionAllowedSetting = {
    YES: true,
    NO: false
};

Framework.Controls.CollapsiblePanelHoldOpen = {
    YES: true,
    NO: false
};

//*********************** smoothe collapsable panel object constructor ***************************
Framework.Controls.CollapsiblePanel = function (panel, trigger, minWidth, minHeight, maxWidth, maxHeight, duration, interval, acceleration, expanded, allowExpansion) {
    this.m_PanelState = null;

    this.m_Panel = panel;
    this.m_Trigger = trigger;
    this.m_AllowExpansion = allowExpansion;
    this.m_Hold = Framework.Controls.CollapsiblePanelHoldOpen.NO;

    this.OnExpandStart = null;
    this.OnExpandComplete = null;
    this.OnCollapseStart = null;
    this.OnCollapseComplete = null;

    if (expanded) {
        this.m_PanelState = Framework.Controls.CollapsiblePanelState.EXPANDED;
        this.SetDimensions(maxWidth, maxHeight);
    }
    else {
        this.m_PanelState = Framework.Controls.CollapsiblePanelState.COLLAPSED;
        this.SetDimensions(minWidth, minHeight);
    }

    this.m_ExpandAnimation = new Framework.Animation.ResizeAnimation(this.m_Panel, maxWidth, maxHeight, duration, interval, acceleration);
    this.m_ExpandAnimation.OnAnimationComplete = Framework.CreateDelegate(this, this.ExpandComplete);

    this.m_CollapseAnimation = new Framework.Animation.ResizeAnimation(this.m_Panel, minWidth, minHeight, duration, interval, acceleration);
    this.m_CollapseAnimation.OnAnimationComplete = Framework.CreateDelegate(this, this.CollapseComplete);

    if (trigger != null) {
        this.AddTrigger(trigger);
    }
};


//*********************** smoothe collapsable panel triger event handler ***************************
Framework.Controls.CollapsiblePanel.prototype.OnTriggerHandler = function (triggerType) {
    if (this.m_PanelState == Framework.Controls.CollapsiblePanelState.ANIMATING) { return; }
    if (triggerType == Framework.Controls.CollapsiblePanelTriggerType.NONE) { return; }

    if (this.m_Hold == Framework.Controls.CollapsiblePanelHoldOpen.YES) {
        this.m_Trigger.OnTriggerMouseOver = Framework.CreateDelegate(this, this.OnTriggerMouseOverHandler);
        this.m_Trigger.OnTriggerMouseOut = Framework.CreateDelegate(this, this.OnTriggerMouseOutHandler);
        this.m_Hold = Framework.Controls.CollapsiblePanelHoldOpen.NO;
    }
    else {
        this.m_Trigger.OnTriggerMouseOver = null;
        this.m_Trigger.OnTriggerMouseOut = null;
        this.m_Hold = Framework.Controls.CollapsiblePanelHoldOpen.YES;
    }
};

Framework.Controls.CollapsiblePanel.prototype.OnTriggerMouseOverHandler = function (triggerType) {
    if (this.m_PanelState == Framework.Controls.CollapsiblePanelState.ANIMATING) { return; }
    if (triggerType == Framework.Controls.CollapsiblePanelTriggerType.NONE) { return; }

    if (this.m_PanelState == Framework.Controls.CollapsiblePanelState.COLLAPSED) {
        if (triggerType != Framework.Controls.CollapsiblePanelTriggerType.EXPAND) {
            this.Expand();
        }
    }
};

Framework.Controls.CollapsiblePanel.prototype.OnTriggerMouseOutHandler = function (triggerType) {
    if (this.m_PanelState == Framework.Controls.CollapsiblePanelState.ANIMATING) { return; }
    if (triggerType == Framework.Controls.CollapsiblePanelTriggerType.NONE) { return; }

    if (this.m_PanelState == Framework.Controls.CollapsiblePanelState.EXPANDED) {
        if (triggerType != Framework.Controls.CollapsiblePanelTriggerType.EXPAND) {
            this.Collapse();
        }
    }
};


//*********************** smoothe collapsable panel methods ***************************
Framework.Controls.CollapsiblePanel.prototype.AddTrigger = function (trigger) {
    trigger.OnTriggerClick = Framework.CreateDelegate(this, this.OnTriggerHandler);
    trigger.OnTriggerMouseOver = Framework.CreateDelegate(this, this.OnTriggerMouseOverHandler);
    trigger.OnTriggerMouseOut = Framework.CreateDelegate(this, this.OnTriggerMouseOutHandler);
};

Framework.Controls.CollapsiblePanel.prototype.Expand = function () {
    if (this.OnExpandStart != null) {
        this.OnExpandStart();
    }

    this.m_PanelState = Framework.Controls.CollapsiblePanelState.ANIMATING;

    this.m_ExpandAnimation.Start();
};

Framework.Controls.CollapsiblePanel.prototype.Collapse = function () {
    if (this.CollapseStart != null) {
        this.OnCollapseStart();
    }

    this.m_PanelState = Framework.Controls.CollapsiblePanelState.ANIMATING;

    this.m_Panel.style.minHeight = "";
    this.m_CollapseAnimation.Start();
};

Framework.Controls.CollapsiblePanel.prototype.ExpandComplete = function () {
    if (this.OnExpandComplete != null) {
        this.OnExpandComplete(this);
    }

    this.m_PanelState = Framework.Controls.CollapsiblePanelState.EXPANDED

    if (this.m_AllowExpansion) {
        this.AllowForExpansion();
    }
};

Framework.Controls.CollapsiblePanel.prototype.CollapseComplete = function () {
    if (this.OnCollapseComplete != null) {
        this.OnCollapseComplete(this);
    }

    this.m_PanelState = Framework.Controls.CollapsiblePanelState.COLLAPSED
};

Framework.Controls.CollapsiblePanel.prototype.SetDimensions = function (width, height) {
    this.m_Panel.style.height = height + 'px';
    this.m_Panel.style.width = width + 'px';
};

Framework.Controls.CollapsiblePanel.prototype.AllowForExpansion = function () {
    this.m_Panel.style.minHeight = this.m_Panel.style.height;
    this.m_Panel.style.height = "";
};


// ***********************************************************************************************************
// Name: Carousel Control
// Type: User Control
// Author: Cliff Gower
//************************************************************************************************************

var Framework = Framework || {};
Framework.Controls = Framework.Controls || {};

//dependencies
//Framework.Animation.js
//Framework.Animation.Animations.js
//Framework.Controls.Button.js
//Framework.CustomEventHandling.js
//Framework.EventHandling.js

Framework.Controls.CarouselOrientation = {
    HORIZONTAL: 0,
    VERTICAL: 1
};

Framework.Controls.CarouselDirection = {
    FORWARD: 0,
    REVERSE: 1
};

Framework.Controls.CarouselEvent = {
    FORWARD: 'forward',
    REVERSE: 'reverse',
    COMPLETE: 'complete'
};



//*************************** Carousel Base Class **********************************
Framework.Controls.CarouselBase = function () {
    this.ContentDiv = null;
    this.MaskDiv = null;

    this.OffsetStart = null;
    this.OffsetEnd = null;

    this.ForwardAnimation = null;
    this.ReverseAnimation = null;

    this.AnimationAcceleration = Framework.Animation.AccelerationType.QUADRATIC_EASE_OUT;

    this.AddEvent(Framework.Controls.CarouselEvent.FORWARD);
    this.AddEvent(Framework.Controls.CarouselEvent.REVERSE);
    this.AddEvent(Framework.Controls.CarouselEvent.COMPLETE);
};

Framework.Controls.CarouselBase.prototype = new Framework.CustomEventHandlingBase();

Framework.Controls.CarouselBase.prototype.InitBase = function (contentDiv, maskDiv, offsetStart, offsetEnd) {
    this.ContentDiv = contentDiv;
    this.MaskDiv = maskDiv;
    this.OffsetStart = offsetStart;
    this.OffsetEnd = offsetEnd;
};

Framework.Controls.CarouselBase.prototype.AddButton = function (button, direction) {
    if (direction == Framework.Controls.CarouselDirection.FORWARD) {
        button.OnButtonClick = Framework.CreateDelegate(this, this.Forward);
    }
    else {
        button.OnButtonClick = Framework.CreateDelegate(this, this.Reverse);
    }

    this.RegisterEventHandler(new Framework.CustomEventHandler(button.ButtonElement.id + Framework.Controls.CarouselEvent.FORWARD,
    Framework.Controls.CarouselEvent.FORWARD,
    Framework.CreateDelegate(button, button.Disable)));

    this.RegisterEventHandler(new Framework.CustomEventHandler(button.ButtonElement.id + Framework.Controls.CarouselEvent.REVERSE,
    Framework.Controls.CarouselEvent.REVERSE,
    Framework.CreateDelegate(button, button.Disable)));

    this.RegisterEventHandler(new Framework.CustomEventHandler(button.ButtonElement.id + Framework.Controls.CarouselEvent.COMPLETE,
    Framework.Controls.CarouselEvent.COMPLETE, 
    Framework.CreateDelegate(button, button.Enable)));
};

Framework.Controls.CarouselBase.prototype.CheckForwardBoundary = function (offset, contentDimension, maskDimension) {
    if (offset <= -(contentDimension - maskDimension)) { return false; }
    else { return true; }
};

Framework.Controls.CarouselBase.prototype.CheckReverseBoundary = function (offset) {
    if (offset == this.OffsetStart) { return false; }
    else {  return true; }
};

Framework.Controls.CarouselBase.prototype.StepAnimationCompleteHandler = function () {
    this.FireEvent(Framework.Controls.CarouselEvent.COMPLETE);
};

Framework.Controls.CarouselBase.prototype.Reverse = function () { };

Framework.Controls.CarouselBase.prototype.Forward = function () { };



//*************************** Horizontal Carousel **********************************
Framework.Controls.HorizontalCarousel = function (contentDiv, maskDiv, increment, itemCount, duration, interval) {
    this.ForwardAnimation = new Framework.Animation.HorizontalMoveByAnimation(contentDiv, -increment, duration, interval, this.AnimationAcceleration);
    this.ForwardAnimation.OnAnimationComplete = Framework.CreateDelegate(this, this.StepAnimationCompleteHandler);

    this.ReverseAnimation = new Framework.Animation.HorizontalMoveByAnimation(contentDiv, increment, duration, interval, this.AnimationAcceleration);
    this.ReverseAnimation.OnAnimationComplete = Framework.CreateDelegate(this, this.StepAnimationCompleteHandler);

    this.InitBase(contentDiv, maskDiv, contentDiv.offsetLeft, contentDiv.offsetLeft);
};

Framework.Controls.HorizontalCarousel.prototype = new Framework.Controls.CarouselBase();

Framework.Controls.HorizontalCarousel.prototype.Reverse = function () {
    if (!this.CheckReverseBoundary()) { return; }

    this.FireEvent(Framework.Controls.CarouselEvent.FORWARD);
    this.ReverseAnimation.Start();
};

Framework.Controls.HorizontalCarousel.prototype.Forward = function () {
    if (!this.CheckForwardBoundary(this.ContentDiv.offsetLeft, this.ContentDiv.clientWidth, this.MaskDiv.clientWidth)) { return; }

    this.FireEvent(Framework.Controls.CarouselEvent.REVERSE);
    this.ForwardAnimation.Start();
};



//*************************** Vertical Carousel **********************************
Framework.Controls.VerticalCarousel = function (contentDiv, maskDiv, increment, itemCount, duration, interval) {
    this.ForwardAnimation = new Framework.Animation.VerticalMoveByAnimation(contentDiv, increment, duration, interval, this.AnimationAcceleration);
    this.ForwardAnimation.OnAnimationComplete = Framework.CreateDelegate(this, this.StepAnimationCompleteHandler);

    this.ReverseAnimation = new Framework.Animation.VerticalMoveByAnimation(contentDiv, -increment, duration, interval, this.AnimationAcceleration);
    this.ReverseAnimation.OnAnimationComplete = Framework.CreateDelegate(this, this.StepAnimationCompleteHandler);

    this.InitBase(contentDiv, maskDiv, contentDiv.offsetTop, contentDiv.offsetTop);
};

Framework.Controls.VerticalCarousel.prototype = new Framework.Controls.CarouselBase();

Framework.Controls.VerticalCarousel.prototype.Reverse = function () {
    if (!this.CheckReverseBoundary(this.ContentDiv.offsetTop)) { return; }

    this.FireEvent(Framework.Controls.CarouselEvent.FORWARD);
    this.ReverseAnimation.Start();
};

Framework.Controls.VerticalCarousel.prototype.Forward = function () {
    if (!this.CheckForwardBoundary(this.ContentDiv.offsetTop, this.ContentDiv.clientHeight, this.MaskDiv.clientHeight)) { return; }

    this.FireEvent(Framework.Controls.CarouselEvent.REVERSE);
    this.ForwardAnimation.Start();
};


// ***********************************************************************************************************
// Name: Scrolling List Control
// Type: User Control
// Author: Cliff Gower
//************************************************************************************************************

var Framework = Framework || {};
Framework.Controls = Framework.Controls || {};

//dependencies
//Framework.Animation.js
//Framework.Animation.Animations.js
//Framework.Controls.Button.js
//Framework.Controls.Carousel.js
//Framework.CustomEventHandling.js
//Framework.EventHandling.js


Framework.Controls.ScrollingListScrollType = {
    SINGLE: 0,
    MULTIPLE: 1
};


//*************************** Scrolling List **********************************
Framework.Controls.ScrollingList = function (contentDiv, maskDiv, itemHeight, itemCount, duration, interval) {
    this.ListItemHeight = itemHeight;
    this.ItemScrollDuration = duration;
    this.ListItemCount = itemCount;
    this.ListItemCurrent = 0;
    this.ListItemScrollToItem = 0;
    this.ListScrollType = Framework.Controls.ScrollingListScrollType.SINGLE;

    this.ForwardAnimation = new Framework.Animation.VerticalMoveByAnimation(contentDiv, -itemHeight, duration, interval, this.AnimationAcceleration);
    this.ForwardAnimation.OnAnimationComplete = Framework.CreateDelegate(this, this.StepAnimationCompleteHandler);

    this.ReverseAnimation = new Framework.Animation.VerticalMoveByAnimation(contentDiv, itemHeight, duration, interval, this.AnimationAcceleration);
    this.ReverseAnimation.OnAnimationComplete = Framework.CreateDelegate(this, this.StepAnimationCompleteHandler);

    this.InitBase(contentDiv, maskDiv, contentDiv.offsetTop, contentDiv.offsetTop);

    this.RegisterEventHandler(new Framework.CustomEventHandler('listscrolltransitioncomplete',
    Framework.Controls.CarouselEvent.COMPLETE,
    Framework.CreateDelegate(this, this.ListScrollCompleteHandler)));
};

Framework.Controls.ScrollingList.prototype = new Framework.Controls.CarouselBase();

Framework.Controls.ScrollingList.prototype.Reverse = function (args) {
    if (this.ListScrollType == Framework.Controls.ScrollingListScrollType.MULTIPLE && args != undefined) { return; }
    if (!this.CheckReverseBoundary(this.ContentDiv.offsetTop)) { return; }

    this.FireEvent(Framework.Controls.CarouselEvent.REVERSE);
    this.ReverseAnimation.Start();

    this.ListItemCurrent--;
};

Framework.Controls.ScrollingList.prototype.Forward = function (args) {
    if (this.ListScrollType == Framework.Controls.ScrollingListScrollType.MULTIPLE && args != undefined) { return; }
    if (!this.CheckForwardBoundary(this.ContentDiv.offsetTop, this.ContentDiv.clientHeight, this.MaskDiv.clientHeight)) { return; }

    this.FireEvent(Framework.Controls.CarouselEvent.FORWARD);
    this.ForwardAnimation.Start();

    this.ListItemCurrent++;
};

Framework.Controls.ScrollingList.prototype.ScrollToItem = function (item) {
    this.ListItemScrollToItem = item;
    this.ListScrollType = Framework.Controls.ScrollingListScrollType.MULTIPLE;
    this.AutoScroll();
};

Framework.Controls.ScrollingList.prototype.AutoScroll = function (item) {
    if (this.ListItemScrollToItem == this.ListItemCurrent) {
        this.ListScrollType = Framework.Controls.ScrollingListScrollType.SINGLE;
    }
    else if (this.ListItemScrollToItem - this.ListItemCurrent > 0) {
        this.Forward();
    }
    else {
        this.Reverse();
    }
};

Framework.Controls.ScrollingList.prototype.ListScrollCompleteHandler = function () {
    if (this.ListScrollType == Framework.Controls.ScrollingListScrollType.MULTIPLE) {
        this.AutoScroll();
    }
};



//*************************** Scrolling List Counter **********************************
Framework.Controls.ScrollingListCounter = function (counterHundredsElement, counterTensElement, counterOnesElement, list) {
    this.CounterHundredsElement = counterHundredsElement;
    this.CounterTensElement = counterTensElement;
    this.CounterOnesElement = counterOnesElement;

    this.List = list;

    this.List.RegisterEventHandler(new Framework.CustomEventHandler('counterlistscrolltransitioncomplete',
    Framework.Controls.CarouselEvent.COMPLETE,
    Framework.CreateDelegate(this, this.ListScrollCompleteHandler)));

    this.UpdateCounter();
};

Framework.Controls.ScrollingListCounter.prototype.UpdateCounter = function () {
    var countString = '';
    countString += parseInt(this.List.ListItemCurrent + 1);
    var countArray = countString.split("");

    this.ClearCounter();

    this.CounterOnesElement.innerHTML = countArray[countArray.length - 1];

    if (countArray.length > 1) {
        this.CounterTensElement.innerHTML = countArray[countArray.length - 2];
    }

    if (countArray.length > 2) {
        this.CounterHundredsElement.innerHTML = countArray[countArray.length - 3];
    }
};

Framework.Controls.ScrollingListCounter.prototype.ClearCounter = function () {
    this.CounterOnesElement.innerHTML = '';
    this.CounterTensElement.innerHTML = '';
    this.CounterHundredsElement.innerHTML = '';
};

Framework.Controls.ScrollingListCounter.prototype.ListScrollCompleteHandler = function () {
    this.UpdateCounter();
};



//*************************** Random Number Generator  **********************************
Framework.Controls.RandomNumberGenerator = function (ceiling, interval) {
    this.Ceiling = ceiling;
    this.Interval = interval;
    this.Timer = null;

    this.OnRandomNumberTimer = null;

    this.RandomNumberTimerDelegate = Framework.CreateDelegate(this, this.RandomNumberIntervalHandler)
};

Framework.Controls.RandomNumberGenerator.prototype.GenerateRandomNumber = function () {
    return randomnumber = Math.floor(Math.random() * this.Ceiling)
};

Framework.Controls.RandomNumberGenerator.prototype.Start = function () {
    if (this.Timer != null) {
        this.Stop();
    }

    this.Timer = setTimeout(this.RandomNumberTimerDelegate, this.Interval);
};

Framework.Controls.RandomNumberGenerator.prototype.Stop = function () {
    clearTimeout(this.Timer);
    this.Timer = null;
};

Framework.Controls.RandomNumberGenerator.prototype.RandomNumberIntervalHandler = function () {
    if (this.OnRandomNumberTimer != null) {
        this.OnRandomNumberTimer(this.GenerateRandomNumber());
    }
};


Framework.Controls.WaysWidget = function () {
    this.RedBanner = null;
    this.List = null;
    this.ListCounter = null;
    this.NumberGenerator = null;

    this.RandomNumberCeiling = 20;

    Framework.AddHandler(window, 'load', Framework.CreateDelegate(this, this.Init));
}

Framework.Controls.WaysWidget.prototype.Init = function () {
    this.RedBanner = new Framework.Controls.CollapsiblePanel(document.getElementById('widget-red-banner'),
    new Framework.Controls.Trigger(document.getElementById('question'), Framework.Controls.CollapsiblePanelTriggerType.BOTH),
    353, 0, 353, 54, 150, 10, Framework.Animation.AccelerationType.QUADRATIC_EASE_OUT,
    Framework.Controls.CollapsiblePanelStartState.COLLAPSED,
    Framework.Controls.CollapsiblePanelExpansionAllowedSetting.NO)

    this.List = new Framework.Controls.ScrollingList(document.getElementById('display-inner-list'), document.getElementById('display'), 27, 3, 150, 10);
    this.List.AddButton(new Framework.Controls.ButtonControl(document.getElementById('scroll-up')), Framework.Controls.CarouselDirection.REVERSE);
    this.List.AddButton(new Framework.Controls.ButtonControl(document.getElementById('scroll-down')), Framework.Controls.CarouselDirection.FORWARD);

    this.ListCounter = new Framework.Controls.ScrollingListCounter(document.getElementById('cent'), document.getElementById('decem'), document.getElementById('unus'), this.List)

    this.NumberGenerator = new Framework.Controls.RandomNumberGenerator(this.RandomNumberCeiling + 1, 6000);
    this.NumberGenerator.OnRandomNumberTimer = Framework.CreateDelegate(this, this.RandomNumberGeneratorTimerHandler);

    this.List.RegisterEventHandler(new Framework.CustomEventHandler('listscrolltransitionforwardhandler',
    Framework.Controls.CarouselEvent.FORWARD,
    Framework.CreateDelegate(this, this.ScrollingListForwardHandler)));

    this.List.RegisterEventHandler(new Framework.CustomEventHandler('listscrolltransitionreversehandler',
    Framework.Controls.CarouselEvent.REVERSE,
    Framework.CreateDelegate(this, this.ScrollingListReverseHandler)));

    this.List.RegisterEventHandler(new Framework.CustomEventHandler('listscrolltransitioncompletehandler',
    Framework.Controls.CarouselEvent.COMPLETE,
    Framework.CreateDelegate(this, this.ScrollingListCompleteHandler)));

    this.List.ScrollToItem(this.NumberGenerator.GenerateRandomNumber());
}
    
Framework.Controls.WaysWidget.prototype.ScrollingListForwardHandler = function () {
    this.NumberGenerator.Stop();
}

Framework.Controls.WaysWidget.prototype.ScrollingListReverseHandler = function () {
    this.NumberGenerator.Stop();
}

Framework.Controls.WaysWidget.prototype.ScrollingListCompleteHandler = function () {
    this.NumberGenerator.Start();
}

Framework.Controls.WaysWidget.prototype.RandomNumberGeneratorTimerHandler = function (randomNumber) {
    var endItem = this.CalculateNextItem(randomNumber);
    this.List.ScrollToItem(endItem);
}

Framework.Controls.WaysWidget.prototype.CalculateNextItem = function (randomNumber) {
    var startItem = this.List.ListItemCurrent - (this.RandomNumberCeiling / 2);
    if(startItem < 0){ 
        startItem = 0;
    }

    var endItem = startItem + randomNumber;
    if(endItem > 100){ 
        endItem = 100;
    }

    if(endItem == this.List.ListItemCurrent) { 
        endItem = this.CalculateNextItem(this.NumberGenerator.GenerateRandomNumber()); 
    }

    return endItem;
}

var waysWidget = new Framework.Controls.WaysWidget();
