var DJR = {};
DJR.Core = {
    setProperties: function (o) {
        this._setGlobalProperties();
        if ($chk(o)) {
            for (var option in o) {
                if (o.hasOwnProperty(option)) {
                    this[option] = o[option];
                }
            }
        }
        this.initCustomEvents();
        return this;
    },
    _setGlobalProperties: function () {
        if (typeof this._name !== 'undefined' && typeof DJROptions !== 'undefined') {
            if (typeof DJROptions[this._name] !== 'undefined') {
                for (var option in DJROptions[this._name]) {
                    if (DJROptions[this._name].hasOwnProperty(option)) {
                        this[option] = DJROptions[this._name][option];
                    }
                }
            }
        }
        return this;
    },
    invokeEvent: function (str, args) {
        var method = 'invoke' + str.capitalize();
        if ($chk(this[method])) {
            this[method](args);
        }
    },
    initCustomEvents: function (events) {
        var e = [];
        if ($chk(events)) {
            e = events;
        } else if ($chk(this.CustomEvents) && !$chk(this._customEventsInitialized)) {
            e = this.CustomEvents.flatten();
            this._customEventsInitialized = true;
        }
        e.each(function (event) {
            this.initCustomEvent(event);
        }.bind(this));
        return this;
    },
    initCustomEvent: function (e) {
        var cap = e.capitalize();
        this['invoke' + cap] = function (args) {
            if ($chk(this['do' + cap])) {
                this['do' + cap](args);
            }
        }.bind(this);
        this['do' + cap] = function (args) {
            args = ($chk(args)) ? args : null;
            this.fireEvent(e, args);
        }.bind(this);
    }
};
DJR.Chrome = new Class({
    Implements: [DJR.Core, Chain, Events],
    el: null,
    initialize: function (el) {
        this.initEl(el);
    },
    initEl: function (el) {
        var me = this;
        this.el = $$(el)[0];
        return this;
    },
    getSize: function () {
        return this.size;
    },
    getScrollSize: function () {
        return {
            width: this.el.getScrollSize().x,
            height: this.el.getScrollSize().y
        };
    },
    getCoordinates: function () {
        return this.el.getCoordinates();
    },
    getAllDimensions: function () {
        return this.el.getAllDimensions();
    }
});
DJR.Utils = {
    body: null,
    html: null,
    ishim: null,
    offscreenHolder: null,
    removeScroll: function () {
        if (!Browser.Engine.gecko18) {
            this.curScrollTop = window.getScroll().y;
            this.html.setStyle('overflow', 'hidden');
        }
    },
    restoreScroll: function () {
        if (!Browser.Engine.gecko18) {
            if ($chk(this.curScrollTop)) {
                window.scrollTo(0, this.curScrollTop);
            }
            this.html.setStyle('overflow', '');
        }
    },
    isChrome: function () {
        return navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
    },
    getQueryStringVal: function (val) {
        var lc = location.search.substring(1);
        var qs = lc.split("&");
        for (var i = 0; i < qs.length; i++) {
            var cur = qs[i].split("=");
            if (cur[0] == val) {
                return cur[1];
            }
        }
        return false;
    },
    getQueryStringVals: function (defaults) {
        var lc = location.search.substring(1),
            qs = lc.split("&"),
            len = qs.length,
            result = {},
            i;
        for (i = 0; i < len; i++) {
            var cur = qs[i].split("=");
            if (typeof cur[1] !== 'undefined') {
                result[cur[0]] = cur[1];
            }
        }
        if (defaults) {
            for (var key in defaults) {
                if (typeof result[key] === 'undefined') {
                    result[key] = defaults[key];
                }
            }
        }
        return result;
    },
    getWindowCenter: function () {
        var winCoords = window.getCoordinates(),
            scroll = window.getScroll(),
            left = (winCoords.width / 2) + scroll.x,
            top = (winCoords.height / 2) + scroll.y;
        return {
            x: left,
            y: top
        };
    },
    getCenterCoords: function (width, height) {
        var winCenter = this.getWindowCenter(),
            left = winCenter.x - (width / 2),
            top = winCenter.y - (height / 2);
        return {
            x: left,
            y: top
        };
    },
    dimsFromCoords: function (coords) {
        var w = coords.right - coords.left;
        var h = coords.bottom - coords.top;
        return {
            width: w,
            height: h
        };
    },
    compassPoints: ['N', 'S', 'E', 'W'],
    directions: ['top', 'bottom', 'left', 'right'],
    dirComplements: {
        'top': 'bottom',
        'bottom': 'top',
        'left': 'right',
        'right': 'left'
    },
    compassComplements: {
        'N': 'S',
        'S': 'N',
        'E': 'W',
        'W': 'E'
    },
    dirToCompass: {
        'top': 'N',
        'bottom': 'S',
        'right': 'E',
        'left': 'W'
    },
    compassToDir: {
        'N': 'top',
        'S': 'bottom',
        'E': 'right',
        'W': 'left'
    },
    HIDDEN_STYLES: {
        width: 1,
        height: 1,
        left: '-1000em',
        top: '-1000em',
        overflow: 'hidden',
        position: 'absolute'
    }
};
window.addEvent('domready', function () {
    DJR.Utils.body = $$('body')[0];
    DJR.Utils.html = $$('html')[0];
    DJR.Utils.offscreenHolder = new Element('div', {
        'class': 'DJR_offscreen_holder',
        'styles': {
            'left': -9999,
            'display': 'none'
        }
    });
    DJR.Utils.body.adopt(DJR.Utils.offscreenHolder);
    DJR.Utils.elementMeasurer = new Element('div', {
        'class': 'DJR_element_measurer',
        'styles': {
            'left': -9999,
            'top': 0,
            'visibility': 'hidden',
            'float': 'left'
        }
    });
    DJR.Utils.body.adopt(DJR.Utils.elementMeasurer);
});
DJR.Cookie = {
    getCookie: function (c_name) {
        if (document.cookie.length > 0) {
            c_start = document.cookie.indexOf(c_name + "=");
            if (c_start != -1) {
                c_start = c_start + c_name.length + 1;
                c_end = document.cookie.indexOf(";", c_start);
                if (c_end == -1) {
                    c_end = document.cookie.length;
                }
                return unescape(document.cookie.substring(c_start, c_end));
            }
        }
        return "";
    },
    setCookie: function (name, value, days) {
        var exdate = new Date();
        exdate.setDate(exdate.getDate() + days);
        document.cookie = name + "=" + value + ((days == null) ? "" : ";expires=" + exdate.toGMTString()) + ";path=/;";
    },
    getParam: function (name, subname) {
        var aSplit = new Array();
        aSplit = name.split("&");
        for (t = 0; t < aSplit.length; t++) {
            var aSplit2 = new Array();
            aSplit2 = aSplit[t].split("=");
            if (aSplit2[0] == subname) {
                return aSplit2[1];
            }
        }
    }
};
DJR.CustomEvents = {
    ShowHide: ['beforeShow', 'afterShow', 'beforeHide', 'afterHide'],
    Click: ['onClick'],
    Resize: ['beforeResize', 'afterResize']
};
DJR.Console = {
    log: function (value) {
        var el = $('console');
        if (el) {
            if (!$chk(value)) {
                value = 'empty string';
            }
            el.adopt((new Element('br')));
            el.appendText(value);
        }
    }
};
Array.implement({
    adjust: function (startValue) {
        var len = this.length,
            idx = null,
            ar = [];
        for (var i = 0; i < len; i++) {
            if (this[i] === startValue) {
                idx = i;
                break;
            }
        }
        if ($chk(idx)) {
            ar[0] = startValue;
            var old = idx;
            if (old === len - 1) {
                old = 0;
            } else {
                old = old + 1;
            }
            var knew = 1;
            do {
                ar[knew] = this[old];
                knew = knew + 1;
                if (old === len - 1) {
                    old = 0;
                } else {
                    old = old + 1;
                }
            } while (old !== idx);
            return ar;
        } else {
            throw new Error('value does not exist in array');
        }
    }
});
Element.implement({
    getInlineStyles: function () {
        var styles = {};
        for (var s in this.style) {
            styles[s] = this.style[s];
        }
        return styles;
    },
    cacheStyles: function (s) {
        this.store('cachedStyles', s);
        return s;
    },
    getCachedStyles: function () {
        return this.retrieve('cachedStyles');
    },
    makeHidden: function () {
        if (!this.hasClass('hidden')) {
            this.cacheStyles(this.getInlineStyles());
            this.setStyles(DJR.Utils.HIDDEN_STYLES);
            this.addClass('hidden');
        }
        return this;
    },
    removeHidden: function () {
        var me = this;
        if (this.hasClass('hidden')) {
            var cs = this.getCachedStyles(),
                styles = {};
            if (!$chk(cs)) {
                cs = this.getInlineStyles();
            }
            for (var hs in DJR.Utils.HIDDEN_STYLES) {
                styles[hs] = ($chk(cs) && $chk(cs[hs])) ? cs[hs] : null;
                if (styles[hs] === null && (hs === 'top')) {
                    styles[hs] = 0;
                }
            }
            this.setStyles(styles);
            this.removeClass('hidden');
        }
        return this;
    },
    applyTempStyles: function (styles) {
        var original = {};
        for (var s in styles) {
            original[s] = this.style[s];
        }
        this.setStyles(styles);
        return original;
    },
    show: function () {
        this.removeHidden();
        return this;
    },
    hide: function () {
        this.makeHidden();
        return this;
    },
    getAllDimensions: function () {
        var dims = {};
        dims.scrollSize = this.getScrollSize();
        dims.scroll = this.getScroll();
        dims.position = this.getPosition();
        dims.coordinates = this.getCoordinates();
        var centerx = dims.coordinates.left + (dims.coordinates.width / 2);
        var centery = dims.coordinates.top + (dims.coordinates.height / 2);
        var N = {
            x: centerx,
            y: dims.coordinates.top
        };
        var NE = {
            x: dims.coordinates.right,
            y: dims.coordinates.top
        };
        var E = {
            x: dims.coordinates.right,
            y: centery
        };
        var SE = {
            x: dims.coordinates.right,
            y: dims.coordinates.bottom
        };
        var S = {
            x: centerx,
            y: dims.coordinates.bottom
        };
        var SW = {
            x: dims.coordinates.left,
            y: dims.coordinates.bottom
        };
        var W = {
            x: dims.coordinates.left,
            y: centery
        };
        var NW = {
            x: dims.coordinates.left,
            y: dims.coordinates.top
        };
        var boxW = dims.coordinates.width - (dims.coordinates.width - this.getStyle('width').toInt());
        var boxH = dims.coordinates.height - (dims.coordinates.height - this.getStyle('height').toInt());
        dims.centerPoint = {
            x: centerx,
            y: centery
        };
        dims.compass = {
            N: N,
            NE: NE,
            E: E,
            SE: SE,
            S: S,
            SW: SW,
            W: W,
            NW: NW
        };
        dims.boxSize = {
            width: boxW,
            height: boxH
        };
        return dims;
    }
});
String.implement({
    makeDom: function () {
        var wrapper = new Element('div', {
            'class': 'DJR_elements_wrapper'
        });
        wrapper.set('html', this);
        DJR.Utils.offscreenHolder.adopt(wrapper);
        return wrapper;
    }
});
Number.implement({
    isEven: function () {
        if (this % 2 == 0) {
            return true;
        } else {
            return false;
        }
    },
    maxDecimals: function (decimals) {
        var multiplier = Math.pow(10, decimals);
        return parseInt(this * multiplier, 10) / multiplier;
    }
});
DJR.IFillable = {
    loader: null,
    content: null,
    contentSize: {
        width: 0,
        height: 0
    },
    contentHolder: null,
    contentWrapper: null,
    contentType: 'empty',
    padding: {
        top: 0,
        right: 0,
        bottom: 0,
        left: 0
    },
    cloneContent: false,
    contentNextSibling: null,
    contentPreviousSibling: null,
    contentParent: null,
    contentIsHidden: false,
    useLoader: true,
    initFillable: function (cloneContent) {
        this.cloneContent = cloneContent || this.cloneContent;
        this.titleHolder = this.el.getElement('.DJR_title');
        this.contentHolder = this.el.getElement('.DJR_content');
        this.initCustomEvents(['onContentLoad', 'onContentHide', 'onContentShow']);
        this._initContentWrapper();
        this._initPadding();
        this._contentTween = new Fx.Tween(this.contentHolder, {
            fps: 24
        });
        return this;
    },
    _initContentWrapper: function () {
        this.contentWrapper = new Element('div', {
            'class': 'DJR_content_wrapper',
            styles: {
                'overflow': 'hidden',
                'zoom': 1,
                'width': 'auto',
                'background-color': '#fff'
            }
        });
        this.contentWrapper.wraps(this.contentHolder);
    },
    _initPadding: function () {
        var klass = this.el.getProperty('class'),
            reT = /T:(\d*)/,
            reR = /R:(\d*)/,
            reB = /B:(\d*)/,
            reL = /L:(\d*)/,
            resT = reT.exec(klass),
            resR = reR.exec(klass),
            resB = reB.exec(klass),
            resL = reL.exec(klass);
        this.padding.top = $chk(resT) ? resT[1].toInt() : 0;
        this.padding.right = $chk(resR) ? resR[1].toInt() : 0;
        this.padding.bottom = $chk(resB) ? resB[1].toInt() : 0;
        this.padding.left = $chk(resL) ? resL[1].toInt() : 0;
        return this;
    },
    showLoader: function () {
        if (this.useLoader) {
            this.contentWrapper.addClass('DJR_loading');
        }
        return this;
    },
    hideLoader: function () {
        this.contentWrapper.removeClass('DJR_loading');
        return this;
    },
    hideContent: function (fade) {
        var styles = {
            'visibility': '',
            'display': 'none',
            'height': 0,
            'width': 0,
            'opacity': 0,
            'filter': 'alpha(opacity=0)'
        };
        fade = fade === false ? false : true;
        if (!this.contentIsHidden) {
            this.showLoader();
            if (fade && !Browser.Engine.trident4 && !Browser.Engine.trident5) {
                this._contentTween.onComplete = function () {
                    this.invokeEvent('onContentHide');
                    this.contentHolder.setStyles(styles);
                    this.contentIsHidden = true;
                }.bind(this);
                this._contentTween.start('opacity', [1, 0]);
            } else {
                this.invokeEvent('onContentHide');
                this.contentIsHidden = true;
                this.contentHolder.setStyles(styles);
            }
        } else {
            this.invokeEvent('onContentHide');
        }
        return this;
    },
    showContent: function (fade) {
        var styles = {
            'display': 'block',
            'height': '100%',
            'width': '100%',
            'visibility': 'visible'
        };
        fade = fade || true;
        if (this.contentIsHidden) {
            if (fade && !Browser.Engine.trident4 && !Browser.Engine.trident5) {
                this._contentTween.onStart = function () {
                    this.contentHolder.setStyles(styles);
                    this.invokeEvent('onContentShow');
                }.bind(this);
                this._contentTween.onComplete = function () {
                    this.contentIsHidden = false;
                    this.hideLoader();
                }.bind(this);
                this._contentTween.start('opacity', [0, 1]);
            } else {
                this.hideLoader();
                styles.opacity = 1;
                styles.filter = 'alpha(opacity=100)';
                this.contentIsHidden = false;
                this.contentHolder.setStyles(styles);
                this.invokeEvent('onContentShow');
            }
        }
        return this;
    },
    hideTitle: function () {
        if (this.titleHolder) {
            this.titleHolder.setStyle('visibility', 'hidden');
        }
        return this;
    },
    showTitle: function () {
        if (this.titleHolder) {
            this.titleHolder.setStyle('visibility', '');
        }
        return this;
    },
    fill: function () {
        this.fillContent().fillTitle();
        return this;
    },
    empty: function () {
        this.emptyTitle().emptyContent();
        return this;
    },
    fillContent: function (content) {
        this.emptyContent();
        if ($chk(content)) {
            this.setContent(content);
        }
        this.contentHolder.adopt(this.content);
        if (this.content && this.content.removeClass) {
            this.content.removeClass('hidden');
        }
        return this;
    },
    emptyContent: function () {
        if (this.content !== null) {
            if (!this.cloneContent) {
                this.putContentBack();
            }
            this.contentHolder.empty();
        }
        return this;
    },
    putContentBack: function () {
        var c = this.contentHolder.getFirst();
        if (c) {
            if (c.retrieve('previousSibling') !== null) {
                c.inject(c.retrieve('previousSibling'), 'after');
            } else if (c.retrieve('nextSibling') !== null) {
                c.inject(c.retrieve('nextSibling'), 'before');
            } else if (c.retrieve('parent') !== null) {
                c.inject(c.retrieve('parent'));
            }
        }
        return this;
    },
    fillTitle: function (title) {
        if ($chk(title)) {
            this.setTitle(title);
        }
        if ($chk(this.titleHolder)) {
            this.emptyTitle();
            this.titleHolder.set('html', this.title);
        }
        return this;
    },
    emptyTitle: function () {
        if ($chk(this.titleHolder)) {
            this.titleHolder.empty();
        }
        return this;
    },
    setContent: function (content) {
        if (content !== null) {
            if ($type(content) === 'string') {
                this.contentType = 'html';
                var re = /^#(.*)/;
                if (content.match(re)) {
                    var res = re.exec(content)[1];
                    this.content = $(res).get('html').makeDom();
                } else {
                    this.content = content.makeDom();
                }
            } else if (content.get('tag') === 'iframe' || content.get('tag') === 'img') {
                if (content.get('tag') === 'iframe') {
                    this.contentType = 'iframe';
                } else {
                    this.contentType = 'image';
                }
                this.content = content;
            } else {
                this.contentType = 'html';
                if (this.cloneContent) {
                    this.content = content.clone().getFirst();
                } else {
                    this.content = content.getFirst() || content.firstChild;
                    if (this.content) {
                        if ($type(this.content) === 'textnode') {
                            this.content = this.content.nodeValue.makeDom();
                        }
                        var ns = typeof this.content.getNext !== 'undefined' ? this.content.getNext() : null;
                        var ps = typeof this.content.getPrevious !== 'undefined' ? this.content.getPrevious() : null;
                        var p = typeof this.content.getParent !== 'undefined' ? this.content.getParent() : null;
                        this.content.store('nextSibling', ns);
                        this.content.store('previousSibling', ps);
                        this.content.store('parent', p);
                        if (this.content.hasClass('hidden')) {
                            this.contentIsHidden = true;
                        }
                    }
                }
            }
        }
        return this;
    },
    getContent: function () {
        return this.content;
    },
    setTitle: function (title) {
        this.title = title;
        return this;
    },
    setContentSize: function (width, height) {
        this.contentSize = {
            width: width,
            height: height
        };
        return this;
    },
    getContentSize: function () {
        return this.contentSize;
    },
    getContentDimensions: function () {
        return this.content.getAllDimensions();
    },
    resizeContentHolder: function (width, height) {
        this.contentHolder.setStyles({
            width: width,
            height: height
        });
        this.setContentSize(width, height);
        return this;
    },
    resizeContentWrapper: function (width, height) {
        this.contentWrapper.setStyles({
            width: width,
            height: height
        });
        return this;
    },
    resizeContentToElement: function () {
        var h = this.size.height - this.padding.top - this.padding.bottom,
            w = this.size.width - this.padding.left - this.padding.right;
        this.content.setStyles({
            width: w,
            height: h
        });
        return this;
    },
    getSizeWithContentCoords: function (width, height) {
        var h = this.padding.top + this.padding.bottom + height,
            w = this.padding.left + this.padding.right + width;
        return {
            width: w,
            height: h
        };
    },
    getPotentialSize: function (contentWidth, contentHeight) {
        var validWidth = this.isValidDimension(contentWidth),
            validHeight = this.isValidDimension(contentHeight),
            content = {
            width: contentWidth,
            height: contentHeight
        };
        if (!validWidth) {
            content.width = '';
        }
        if (!validHeight) {
            content.height = '';
        }
        return this.measureElementAndContent(content.width, content.height);
    },
    measureElementAndContent: function (contentWidth, contentHeight) {
        var original = {},
            holderOriginal = {},
            cOriginal = {},
            wrapperOriginal = {},
            clearDiv = null,
            elWidth = 0,
            elHeight = 0,
            cWidth = 0,
            cHeight = 0;
        var measureWrapper = this.measureEl.getElement('.DJR_content_wrapper'),
            measureHolder = this.measureEl.getElement('.DJR_content');
        original = this.measureEl.applyTempStyles({
            'width': '',
            'height': '',
            'visibility': 'hidden',
            'display': ''
        });
        wrapperOriginal = measureWrapper.applyTempStyles({
            'width': '',
            'height': ''
        });
        holderOriginal = measureHolder.applyTempStyles({
            'float': 'right',
            'width': contentWidth,
            'height': contentHeight,
            'border': '1px solid black',
            'display': ''
        });
        clearDiv = new Element('div', {
            styles: {
                'clear': 'both',
                'height': 0,
                'line-height': 0,
                'overflow': 'hidden'
            }
        });
        if (contentWidth === '' || contentHeight === '') {
            measureHolder.adopt(this.content);
        }
        this.measureEl.removeClass('hidden');
        if (this.content && this.content.hasClass('hidden')) {
            this.content.removeClass('hidden');
        }
        clearDiv.inject(measureHolder, 'after');
        cWidth = measureHolder.offsetWidth;
        cHeight = measureHolder.offsetHeight;
        elHeight = (this.measureEl.offsetHeight - this.measureEl.getStyle('padding-top').toInt() - this.measureEl.getStyle('padding-bottom').toInt());
        elWidth = cWidth + this.padding.right + this.padding.left;
        this.measureEl.addClass('hidden');
        clearDiv.destroy();
        this.measureEl.setStyles(original);
        measureHolder.setStyles(holderOriginal);
        measureWrapper.setStyles(wrapperOriginal);
        return {
            element: {
                width: elWidth - 2,
                height: elHeight - 2
            },
            content: {
                width: cWidth - 2,
                height: cHeight - 2
            }
        };
    },
    isValidDimension: function (d) {
        return $chk(d) && $type(d) === 'number' && d > 1;
    },
    addScroll: function () {
        if (this.contentHolder.getStyle("overflow") !== "auto") {
            this.contentHolder.setStyle("overflow", "auto");
        }
    },
    removeScroll: function () {
        if (this.contentHolder.getStyle("overflow")) {
            this.contentHolder.setStyle("overflow", "");
        }
    }
};
DJR.IToggleable = {
    shim: null,
    speed: 1000,
    initToggleable: function () {
        this.initCustomEvents(DJR.CustomEvents.ShowHide);
        this.initTransitions();
        this.initShim();
        return this;
    },
    initShim: function () {
        if (Browser.Engine.trident4) {
            this.shim = new DJR.Ishim(this.el);
            this.shim.el.setStyle('z-index', 999);
        }
        return this;
    },
    initTransitions: function () {
        this.transition = new Fx.Elements([this.contentWrapper, this.el], {
            duration: this.speed,
            fps: 24,
            transition: Fx.Transitions.Expo.easeInOut
        });
        return this;
    },
    show: function (args) {
        this.invokeEvent('beforeShow');
        this.showShim(this.elShowTransition);
        this.transition.onComplete = function () {
            this.visible = true;
            this.invokeEvent('afterShow');
        }.bind(this);
        this.transition.start({
            '0': this.wrapperShowTransition,
            '1': this.elShowTransition
        });
        return this;
    },
    hide: function (hideArgs) {
        this.invokeEvent('beforeHide');
        this.transition.onComplete = function () {
            this.visible = false;
            this.invokeEvent('afterHide');
            this.hideShim();
        }.bind(this);
        this.transition.start({
            '0': this.wrapperHideTransition,
            '1': this.elHideTransition
        });
        return this;
    },
    showShim: function (coords) {
        var coords = coords || null;
        if ($chk(this.shim)) {
            this.shim.show(coords);
        }
        return this;
    },
    hideShim: function () {
        if ($chk(this.shim)) {
            this.shim.hide();
        }
        return this;
    },
    cancel: function () {
        this.transition.cancel();
        return this;
    },
    updateTransitions: function (values, retract) {
        var show = {},
            hide = {},
            v = values;
        retract = retract !== false ? true : false;
        if (this.isVisible()) {
            show = {
                'width': [this.elShowTransition.width[1], v.endWidth],
                'height': [this.wrapperShowTransition.height[1], v.endWrapperHeight],
                'left': [this.elShowTransition.left[1], v.endLeft],
                'top': [this.elShowTransition.top[1], v.endTop]
            };
        } else {
            show = {
                'opacity': [0, 1],
                'width': [v.startWidth, v.endWidth],
                'height': [v.startWrapperHeight, v.endWrapperHeight],
                'left': [v.startLeft, v.endLeft],
                'top': [v.startTop, v.endTop]
            };
        }
        if (retract) {
            hide = {
                'opacity': [1, 0],
                'width': [v.endWidth, 0],
                'height': [v.endWrapperHeight, 0],
                'left': [v.endLeft, v.startLeft],
                'top': [v.endTop, v.startTop]
            };
        } else {
            hide = {
                'opacity': [1, 0],
                'width': [0, 0],
                'height': [0, 0],
                'left': [-9999, -9999],
                'top': [-9999, -9999]
            };
        }
        this.updateWrapperShowTransition({
            height: show.height
        });
        this.updateWrapperHideTransition({
            height: hide.height
        });
        this.updateElShowTransition({
            top: show.top,
            left: show.left,
            width: show.width,
            opacity: show.opacity
        });
        this.updateElHideTransition({
            top: hide.top,
            left: hide.left,
            width: hide.width,
            opacity: hide.opacity
        });
        return this;
    },
    isVisible: function () {
        return this.visible;
    },
    updateWrapperShowTransition: function (obj) {
        this.wrapperShowTransition = obj;
        return this;
    },
    updateWrapperHideTransition: function (obj) {
        this.wrapperHideTransition = obj;
        return this;
    },
    updateElShowTransition: function (obj) {
        this.elShowTransition = obj;
        return this;
    },
    updateElHideTransition: function (obj) {
        this.elHideTransition = obj;
        return this;
    }
};
DJR.IResizable = {
    size: {
        width: 0,
        height: 0
    },
    initResizable: function () {
        this.initCustomEvents(DJR.CustomEvents.Resize);
        return this;
    },
    setSize: function (width, height) {
        this.size = {
            width: width,
            height: height
        };
        return this;
    },
    getSize: function () {
        return this.size;
    },
    resize: function (width, height) {
        var h = height,
            w = width;
        this.invokeEvent('beforeResize', [w, h]);
        this.el.setStyles({
            width: w,
            height: h
        });
        if ($type(h) === 'string') {
            h = this.el.getSize().y;
        }
        if ($type(w) === 'string') {
            w = this.el.getSize().x;
        }
        this.setSize(w, h);
        this.invokeEvent('afterResize', [w, h]);
        return this;
    }
};
DJR.Measure = {
    getWindowCenter: function () {
        var winCoords = window.getCoordinates(),
            scroll = window.getScroll(),
            left = (winCoords.width / 2) + scroll.x,
            top = (winCoords.height / 2) + scroll.y;
        return {
            x: left,
            y: top
        };
    },
    getCenterCoords: function (width, height) {
        var winCenter = this.getWindowCenter(),
            left = winCenter.x - (width / 2),
            top = winCenter.y - (height / 2);
        return {
            x: left,
            y: top
        };
    },
    dimsFromCoords: function (coords) {
        var w = coords.right - coords.left;
        var h = coords.bottom - coords.top;
        return {
            width: w,
            height: h
        };
    },
    fitToWindow: function (width, height, x, y, marginleft, margintop, marginbottom) {
        var dims = {
            width: width,
            height: height,
            x: x,
            y: y,
            correction: false,
            diff: 0
        },
            winCoords = window.getCoordinates(),
            scroll = window.getScroll(),
            bottom = dims.y + Math.floor(height);
        var barrierBottom = (winCoords.height) + scroll.y - marginbottom,
            barrierTop = scroll.y + margintop,
            tDiff = barrierTop - dims.y,
            bDiff = bottom - barrierBottom,
            diff = tDiff + bDiff;
        dims.diff = diff;
        if (diff > 0) {
            dims.height = height - diff;
            if (dims.y < barrierTop) {
                dims.y = margintop;
            }
            dims.width = dims.width + 17;
            dims.correction = true;
        } else {
            dims.diff = 0;
        }
        if (dims.x < marginleft) {
            dims.x = marginleft;
            dims.correction = true;
        }
        return dims;
    },
    getPixelsInView: function (coords) {
        var win = window.getCoordinates();
        var scroll = window.getScroll();
        var shownWidth = win.width - Math.max((coords.left - scroll.x), 0) - Math.max((win.right - (coords.right - scroll.x)), 0);
        var shownHeight = win.height - Math.max((coords.top - scroll.y), 0) - Math.max((win.bottom - (coords.bottom - scroll.y)), 0);
        var pix = shownWidth * shownHeight;
        return pix > 0 ? pix : 0;
    }
};
DJR.SpaceNegotiator = {
    offsets: {
        top: [0, 0],
        right: [0, 0],
        bottom: [0, 0],
        left: [0, 0]
    },
    results: {
        top: {
            top: 0,
            left: 0
        },
        right: {
            top: 0,
            left: 0
        },
        bottom: {
            top: 0,
            left: 0
        },
        left: {
            top: 0,
            left: 0
        }
    },
    extraPadding: 0,
    negotiate: function (attemptedDir, targetSize, fenceCoords, offsets, extraPadding, relativeTo) {
        var me = this;
        extra = extraPadding || 0;
        relativeTo = relativeTo || window;
        offsets = $merge(this.offsets, offsets);
        var positions = this.getPositions(offsets, targetSize.width, targetSize.height, fenceCoords, extra);
        return this.calculate(attemptedDir, positions, targetSize, extra, relativeTo);
    },
    calculate: function (attemptedDir, pos, targetSize, extra, relativeTo) {
        var pixels = 0;
        var winner = null;
        var fallbacks = [];
        var dirs = DJR.Utils.directions.adjust(attemptedDir);
        var makeWinner = function (dir) {
            var dims = DJR.Utils.dimsFromCoords(pos[dir]);
            var width = dims.width;
            var height = dims.height;
            var fallbacks = [];
            if (dir === 'top' || dir === 'bottom') {
                height = dims.height - extra;
            } else {
                width = dims.width - extra;
            }
            winner = {
                dir: dir,
                top: pos[dir].top,
                left: pos[dir].left,
                bottom: pos[dir].bottom,
                right: pos[dir].right,
                width: width,
                height: height
            };
        };
        for (var i = 0, len = dirs.length; i < len; i++) {
            var dir = dirs[i];
            if (dir === 'top' || dir === 'bottom') {
                pixels = (targetSize.width * targetSize.height) + (extra * targetSize.width);
            } else {
                pixels = (targetSize.width * targetSize.height) + (extra * targetSize.height);
            }
            var pixelsInView = this.getPixelsInView(pos[dir], relativeTo);
            var allVisible = true;
            if (pixelsInView < pixels) {
                allVisible = false;
            }
            if (attemptedDir === dir && allVisible) {
                makeWinner(attemptedDir);
                break;
            } else if (allVisible && dir == DJR.Utils.dirComplements[attemptedDir]) {
                makeWinner(dir);
                break;
            } else if (pos[dir].top > 0 && pos[dir].left > 0) {
                fallbacks.push({
                    dir: dir,
                    pixels: pixelsInView
                });
            }
        }
        if (!$chk(winner)) {
            var px = 0;
            var wn = attemptedDir;
            fallbacks.each(function (fb) {
                if (fb.pixels > px) {
                    px = fb.pixels;
                    wn = fb.dir;
                }
            });
            makeWinner(wn);
        }
        return winner;
    },
    getPixelsInView: function (coords, relativeTo) {
        var win = relativeTo.getCoordinates();
        var scroll = relativeTo.getScroll();
        var shownWidth = win.width - Math.max((coords.left - scroll.x), 0) - Math.max((win.right - (coords.right - scroll.x)), 0);
        var shownHeight = win.height - Math.max((coords.top - scroll.y), 0) - Math.max((win.bottom - (coords.bottom - scroll.y)), 0);
        var pix = shownWidth * shownHeight;
        return pix > 0 ? pix : 0;
    },
    getPositions: function (offsets, w, h, fence, extra) {
        var pos = $merge(this.results, {});
        pos.top.top = fence.top - (h + extra) - offsets.top[1];
        pos.top.left = fence.left + offsets.top[0];
        pos.top.right = pos.top.left + w;
        pos.top.bottom = pos.top.top + h + extra;
        pos.right.top = fence.top + offsets.right[1];
        pos.right.left = fence.right + offsets.right[0];
        pos.right.right = pos.right.left + w + extra;
        pos.right.bottom = pos.right.top + h;
        pos.bottom.top = fence.bottom + offsets.bottom[1];
        pos.bottom.left = fence.left + offsets.bottom[0];
        pos.bottom.right = pos.bottom.left + w;
        pos.bottom.bottom = pos.bottom.top + h + extra;
        pos.left.top = fence.top + offsets.left[1];
        pos.left.left = fence.left - (w + extra) - offsets.left[0];
        pos.left.right = pos.left.left + w + extra;
        pos.left.bottom = pos.left.top + h;
        return pos;
    }
};
DJR.Trigger = new Class({
    Implements: [DJR.Core, Chain, Events],
    triggers: null,
    friends: [],
    over: null,
    out: null,
    click: null,
    blurTimeout: null,
    stopCurrentEvent: $lambda,
    timeout: 0,
    initialize: function (triggers, o) {
        if ($type(triggers) === 'array') {
            this.triggers = triggers;
        } else {
            this.triggers = [triggers];
        }
        this.setProperties(o).bindEvents();
    },
    bindEvents: function () {
        if ($chk(this.over)) {
            this.bindOver(this.over);
        }
        if ($chk(this.out)) {
            this.bindOut(this.out);
        }
        if ($chk(this.click)) {
            this.bindClick(this.click);
        }
        if ($chk(this.focus)) {
            this.bindFocus(this.focus);
        }
        if ($chk(this.blur)) {
            this.bindBlur(this.blur);
        }
    },
    bindEvent: function (which, fn) {
        this.triggers.each(function (trig, index) {
            trig.addEvent(which, function (e) {
                this.currentTimeout = setTimeout(function () {
                    this._theEvent(e, which, trig, fn, index);
                }.bind(this), this.timeout);
            }.bind(this));
        }.bind(this));
    },
    _theEvent: function (e, which, trigger, fn, index) {
        this.friends.include(trigger);
        this.currentEvent = e;
        if (this.isFriend(e, trigger, which)) {
            return this.stopCurrentEvent();
        }
        if (which === 'blur' || which === 'focus') {
            if (which !== 'mouseout') {
                timeoutFunc = function () {
                    fn.attempt(index, trigger);
                };
                clearTimeout(this.blurTimeout);
                this.blurTimeout = setTimeout(timeoutFunc, 10);
            }
        } else {
            fn.attempt(index, trigger);
        }
    },
    bindOver: function (fn) {
        this.bindEvent('mouseover', fn);
        this.bindEvent('focus', fn);
    },
    bindOut: function (fn) {
        this.bindEvent('mouseout', fn);
        this.bindEvent('blur', fn);
    },
    bindFocus: function (fn) {
        this.bindEvent('focus', fn);
    },
    bindBlur: function (fn) {
        this.bindEvent('blur', fn);
    },
    bindClick: function (fn) {
        this.triggers.each(function (trig, index) {
            trig.addEvents({
                'click': function (event) {
                    fn.attempt(index, this);
                    event.stop();
                },
                'keydown': function (event) {
                    if (event.key == 'enter') {
                        window.location = this.href;
                        event.stop();
                    }
                }
            });
        });
    },
    isFriend: function (event, trigger, eventType) {
        var bool = false;
        this.friends.each(function (f, index) {
            if (f == event.target && f !== trigger) {
                bool = true;
            }
            if (f == event.relatedTarget) {
                bool = true;
            }
            if (f.hasChild(event.relatedTarget)) {
                bool = true;
            }
            if (f.hasChild(event.target) && eventType !== 'mouseout' && f !== trigger) {
                bool = true;
            }
        });
        return bool;
    },
    makeFriends: function (friends) {
        if ($type(friends) === 'array') {
            this.friends = friends;
        } else {
            this.friends = [friends];
        }
    },
    removeFriends: function () {
        this.friends = [];
    },
    stopCurrentEvent: function () {
        if (typeof this.currentEvent !== 'undefined') {
            if (this.currentEvent.event.stopPropagation) {
                this.currentEvent.event.stopPropagation();
            } else if (typeof this.currentEvent.event.cancelBubble !== 'unknown') {
                this.currentEvent.event.cancelBubble = true;
            }
            if (this.currentEvent.event.preventDefault) {
                this.currentEvent.event.preventDefault();
            } else if (this.currentEvent.event && typeof this.currentEvent.event.returnValue !== 'unknown') {
                this.currentEvent.event.returnValue = false;
            }
        }
        return;
    },
    invoke: function (which) {}
});
DJR.IFrameManager = {
    count: 1,
    curFrameId: 'DJR_iframe_1',
    iframes: {},
    holder: null,
    create: function (args) {
        var me = this;
        var frameId = 'DJR_iframe_' + me.count;
        var scrolling = typeof args.scrolling !== 'undefined' ? args.scrolling : 'no';
        var iframe = new IFrame({
            'id': frameId,
            'name': frameId,
            'src': args.path,
            'frameborder': '0',
            'scrolling': scrolling,
            'marginheight': '0',
            'marginwidth': '0',
            styles: args.styles,
            onload: function (doc) {
                me.doOnload(doc, this, frameId, args);
            }
        });
        this.count = this.count + 1;
        this.iframes[frameId] = {};
        this.iframes[frameId]['frame'] = iframe;
        return iframe;
    },
    doOnload: function (doc, win, frameId, args) {
        var frame = this.iframes[frameId]['frame'];
        if ($type(args.load) === 'function') {
            args.load.call(frame, doc, win);
        }
    }
};
$extend(DJR.IFrameManager, DJR.Core);
DJR.Ishim = new Class({
    Implements: [DJR.Core, Events, Chain],
    _name: 'Ishim',
    path: 'javascript:"";',
    parent: null,
    el: null,
    coords: {
        top: 0,
        left: 0,
        width: 'auto',
        height: 'auto'
    },
    zIndex: 100000,
    initialize: function (parent, args) {
        args = args || {};
        this.parent = parent || null;
        this.setProperties(args);
        this.initShim().initToggler().initCoords();
    },
    initShim: function () {
        this.el = DJR.IFrameManager.create({
            path: this.path,
            styles: {
                'position': 'absolute',
                'top': 0,
                'left': 0,
                'cursor': 'pointer',
                'opacity': .01,
                'filter': 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=1)',
                'z-index': this.zIndex,
                'display': 'none',
                'overflow': 'hidden'
            }
        });
        DJR.Utils.body.adopt(this.el);
        return this;
    },
    initToggler: function () {
        this.toggler = new DJR.Toggler(this.el);
        return this;
    },
    initCoords: function () {
        if ($chk(this.parent)) {
            this.coords = this.getParentDims();
        }
    },
    getParentDims: function () {
        var c = {};
        if ($chk(this.parent)) {
            c = this.parent.getCoordinates();
        } else {
            c = this.coords;
        }
        return {
            top: c.top,
            left: c.left,
            width: c.width,
            height: c.height
        };
    },
    reposition: function (coords) {
        var c = $merge(this.getParentDims(), coords);
        this.el.setStyles({
            top: c.top,
            left: c.left,
            width: c.width,
            height: c.height
        });
    },
    show: function (coords) {
        if ($chk(coords)) {
            this.reposition(coords);
        } else {
            this.reposition();
        }
        this.toggler.show();
    },
    hide: function () {
        this.reposition({
            top: 0,
            left: 0,
            width: 0,
            height: 0
        });
        this.toggler.hide();
    }
});
DJR.Toggler = new Class({
    Implements: [DJR.Core, DJR.ShowHideable, Chain, Events],
    el: null,
    visible: false,
    transition: null,
    transitionShow: {},
    transitionHide: {},
    CustomEvents: [DJR.CustomEvents.ShowHide, DJR.CustomEvents.Click],
    initialize: function (el, o) {
        this.setElement(el).setProperties(o).initType();
    },
    initType: function () {
        var hidden = false;
        var displaynone = false;
        var type = $chk(this.type) ? this.type : 'displaynone';
        if (this.el.hasClass('hidden')) {
            hidden = true;
        }
        if (this.el.getStyle('display') == 'none') {
            displaynone = true;
        }
        if (hidden && !displaynone) {
            type = 'hidden';
        }
        if (hidden && displaynone) {
            type = 'both';
        }
        this.type = type;
        return this;
    },
    getTransitionKeys: function () {
        var show = [];
        var hide = [];
        for (var key in this.transitionShow) {
            show.push(key);
        }
        for (var key2 in this.transitionHide) {
            hide.push(key2);
        }
        return {
            show: show,
            hide: hide
        };
    },
    toggle: function (which) {
        var me = this;
        var state = $type(which) == "string" ? (which.capitalize()) : (this.isVisible() ? "Hide" : "Show");
        var visible = state == "Show" ? true : false;
        this.invokeEvent('before' + state);
        if (this.transition == null) {
            this.toggleStates(visible);
            this.visible = visible;
            this.invokeEvent('after' + state);
        } else {
            this.transition.cancel();
            this.transition.removeEvents('complete');
            this.transition.addEvent('complete', function () {
                if (!visible) {
                    me.toggleStates(visible);
                }
                me.visible = visible;
                me.invokeEvent('after' + state);
            });
            this.el.setStyle('overflow', 'hidden');
            this.transition.start(this['transition' + state]);
            if (visible) {
                if ($chk(this.transitionShow.opacity)) {
                    this.el.setStyle('visibility', 'hidden');
                }
                me.toggleStates(visible);
            }
        }
        return this;
    },
    show: function () {
        this.toggle('show');
        return this;
    },
    hide: function () {
        this.toggle('hide');
        return this;
    },
    isVisible: function () {
        return this.visible === true ? true : false;
    },
    setElement: function (el) {
        this.el = el;
        return this;
    },
    makeHidden: function () {
        this.el.makeHidden();
    },
    removeHidden: function () {
        this.el.removeHidden();
    },
    makeDisplaynone: function () {
        this.el.setStyle('display', null);
    },
    removeDisplaynone: function () {
        this.el.setStyle('display', 'none');
    },
    toggleStates: function (visible) {
        switch (this.type) {
        case "displaynone":
            this[(visible ? 'make' : 'remove') + 'Displaynone']();
            break;
        case "hidden":
            this[(visible ? 'remove' : 'make') + 'Hidden']();
            break;
        case "both":
            this[(visible ? 'make' : 'remove') + 'Displaynone']();
            this[(visible ? 'remove' : 'make') + 'Hidden']();
            break;
        default:
            break;
        }
    }
});
DJR.Overlay = new Class({
    Implements: [DJR.Core, Chain, Events],
    CustomEvents: [DJR.CustomEvents.ShowHide, DJR.CustomEvents.Click],
    opacity: 0.75,
    color: '#000',
    zIndex: 1000,
    cursor: 'pointer',
    parent: null,
    hideOnClick: false,
    el: null,
    shim: null,
    click: $lambda(true),
    visible: false,
    fade: false,
    initialize: function (o) {
        this.setProperties(o).initElement().initShim().initToggler().bindResizeEvent().bindClickEvent().bindShowHideEvents();
    },
    initElement: function () {
        this.el = new Element('DIV', {
            'class': 'DJR_overlay',
            styles: {
                position: 'absolute',
                top: 0,
                left: 0,
                'background-color': this.color,
                cursor: this.cursor,
                opacity: this.opacity,
                'filter': "alpha(opacity=" + (this.opacity * 100) + ")",
                'z-index': this.zIndex,
                display: 'none',
                width: '100%',
                height: '100%',
                overflow: 'hidden'
            }
        });
        if (this.parent !== null) {
            this.parent.adopt(this.el);
        } else {
            this.parent = DJR.Utils.body;
            this.parent.adopt(this.el);
        }
        return this;
    },
    initShim: function () {
        if (Browser.Engine.trident4) {
            this.shim = new DJR.Ishim(this.el);
        }
        return this;
    },
    initToggler: function () {
        var me = this;
        this.toggler = new DJR.Toggler(this.el);
        if (this.fade === true) {
            this.toggler.transition = new Fx.Morph(me.el);
            this.toggler.transitionShow = {
                'opacity': [0, me.opacity]
            };
            this.toggler.transitionHide = {
                'opacity': [me.opacity, 0]
            };
        }
        return this;
    },
    bindResizeEvent: function () {
        var me = this;
        window.addEvent('resize', function () {
            me.refresh();
        });
        return this;
    },
    bindClickEvent: function () {
        var me = this;
        this.el.addEvent('click', function () {
            if (me.hideOnClick === true) {
                me.hide();
            }
            me.invokeEvent('onClick');
        });
        return this;
    },
    bindShowHideEvents: function () {
        var me = this;
        this.toggler.addEvent('afterShow', function () {
            me.visible = true;
            me.invokeEvent('afterShow');
        });
        this.toggler.addEvent('afterHide', function () {
            me.visible = false;
            me.invokeEvent('afterHide');
        });
        return this;
    },
    show: function () {
        var me = this;
        this.fireEvent('beforeShow');
        this.refresh();
        this.toggler.show();
        if ($chk(this.shim)) {
            this.shim.show();
        }
        return this;
    },
    hide: function () {
        var me = this;
        this.fireEvent('beforeHide');
        this.toggler.hide();
        if ($chk(this.shim)) {
            this.shim.hide();
        }
        return this;
    },
    refresh: function () {
        var height = this.parent.getScrollSize().y,
            width = this.parent.getScrollSize().x;
        if (Browser.Engine.trident4) {
            width = width - 2;
        } else if (Browser.Engine.webkit) {
            if (height > this.parent.getSize().y) {
                width = width - 17;
            }
        }
        this.el.setStyles({
            'height': height,
            'width': width
        });
        if ($chk(this.shim)) {
            this.shim.reposition();
        }
        return this;
    },
    isVisible: function () {
        return this.visible;
    },
    setColor: function (color) {
        this.color = color;
        this.el.setStyle('background-color', color);
    }
});

DJR.Layer = new Class({
    Implements: [DJR.Core, Events, Chain],
    CustomEvents: [DJR.CustomEvents.ShowHide, 'onContentLoad'],
    chrome: null,
    overlay: null,
    useLoader: true,
    useOverlay: true,
    closable: true,
    hideOnOverlayClick: true,
    _name: "Layer",
    _visible: false,
    _busy: false,
    _currentBase: null,
    _initialBase: null,
    initialize: function (o) {
        this.setProperties(o);
        this.bindChromeEvents();
        return this;
    },
    _afterShow: function () {
        this._busy = false;
        this.bindCloseEvent();
        this.invokeEvent('afterShow', [this._currentBase]);
    },
    _afterHide: function () {
        this._busy = false;
        this._initialBase = null;
        this.invokeEvent('afterHide', [this._currentBase]);
    },
    _onContentShow: function () {
        this.bindCloseEvent();
    },
    bindChromeEvents: function () {
        this.removeChromeEvents();
        this.chrome.addEvents({
            'afterShow': (this._afterShow.bind(this)),
            'afterHide': (this._afterHide.bind(this))
        });
    },
    removeChromeEvents: function () {
        this.chrome.removeEvent('afterShow', this._afterShow);
        this.chrome.removeEvent('afterHide', this._afterHide);
    },
    setChrome: function (chrome) {
        this.chrome = chrome;
        return this;
    },
    getChrome: function () {
        return this.chrome;
    },
    show: function (content, args) {
        if (!this.isBusy()) {
            this.removeCloseEvent();
            this._busy = true;
            var c = this.parseContent(content, args.clone);
            if (typeof args.type === 'undefined') {
                args.type = c.type;
            }
            args.content = c.content;
            args.closable = typeof args.closeable !== 'undefined' ? args.closable : this.closable;
            this._currentBase = args.base || this._currentBase;
            args.base = this._currentBase;
            if (this._initialBase === null) {
                this._initialBase = this._currentBase;
            }
            args.initialBase = this._initialBase;
            this.invokeEvent('beforeShow', [args.base]);
            DJR.Layer.Strategy.Show[args.type].call(this, args);
        }
        return this;
    },
    hide: function () {
        if (!this.isBusy()) {
            this.removeCloseEvent();
            this._busy = true;
            this.invokeEvent('beforeHide', [this._currentBase]);
            this.hideOverlay();
            this.chrome.hide();
        }
        return this;
    },
    _close: function () {
        this.hide();
    },
    bindCloseEvent: function () {
        this.removeCloseEvent();
        this.chrome.addEvent('closeClick', this._close.bind(this));
        return this;
    },
    removeCloseEvent: function () {
        this.chrome.removeEvents('closeClick');
        return this;
    },
    showLoader: function () {
        if (this.useLoader) {
            this.chrome.showLoader();
        }
        return this;
    },
    hideLoader: function () {
        if (this.useLoader) {
            this.chrome.hideLoader();
        }
        return this;
    },
    showOverlay: function () {
        if (this.useOverlay) {
            DJR.Utils.overlay.show();
        }
        return this;
    },
    hideOverlay: function () {
        if (this.useOverlay) {
            DJR.Utils.overlay.hide();
        }
        return this;
    },
    isVisible: function () {
        return this._visible;
    },
    isBusy: function () {
        return this._busy;
    },
    parseContent: function (content, clone) {
        var type, c = content;
        if (typeof content === 'undefined' || content === null) {
            type = 'empty';
        } else if ($type(content) === 'element') {
            type = 'html';
        } else if (content.match('#')) {
            var el = $(content.replace('#', ''));
            if (clone) {
                c = el.getFirst().clone();
            } else {
                c = el;
            }
            type = 'html';
        } else if (content.match(/(.jpg|.gif|.png|.bmp)/)) {
            type = 'image';
        } else {
            type = 'iframe';
        }
        return {
            type: type,
            content: c
        };
    }
});
DJR.Layer.Strategy = {
    Show: {
        html: function (args) {
            this.showOverlay();
            this.showLoader();
            this.chrome.setContent(args.content);
            this.chrome.prepare(args);
            this.chrome.show();
        },
        image: function (args) {
            this.showOverlay();
            this.showLoader();
            this.chrome.prepare(args);
        },
        iframe: function (args) {
            this.showOverlay();
            this.showLoader();
            this.chrome.prepare(args);
        },
        empty: function (args) {
            var args = args || {};
            args.type = 'empty';
            this.showOverlay();
            this.showLoader();
            this.chrome.prepare(args);
            this.chrome.show(args);
        }
    },
    Hide: {
        html: function () {}
    }
};
DJR.Layer.Manager = {
    layers: [],
    chromes: {},
    queue: [],
    _current: null,
    defaultChrome: 'DEFAULT',
    init: function () {
        this.initChromes();
        this.initLayer();
    },
    initChromes: function () {
        for (var l in DJR.Templates.Html.Layers) {
            this.chromes[l] = new DJR.Layer.Chrome(DJR.Templates.Html.Layers[l], DJR.Templates.Html.Layers[l + "_MEASURE"]);
        }
        return this;
    },
    initLayer: function () {
        this.layers[0] = new DJR.Layer({
            chrome: this.chromes[this.defaultChrome]
        });
        this._setCurrent(this.layers[0]);
        this.get().addEvents({
            'afterShow': function () {
                this.next();
            }.bind(this),
            'beforeHide': function () {
                this.cancel();
            }.bind(this)
        });
        return this;
    },
    show: function (content, args) {
        var a = args || {};
        a.chrome = $chk(a.chrome) ? this.chromes[a.chrome.toUpperCase()] : this.chromes["DEFAULT"];
        a.type = $chk(a.type) ? a.type : (this.determineContentType(content));
        if (a.type === 'iframe') {
            DJR.Layer.Manager.show(null, {
                base: a.base,
                toggleStrategy: a.toggleStrategy
            });
        }
        var g = this.get();
        if (g.isBusy()) {
            this.addToQueue('show', content, a);
        } else {
            g.show(content, a);
        }
        return this;
    },
    hide: function (args) {
        var l = this.get();
        if (l !== null) {
            if (l.isBusy()) {
                this.cancel();
                this.addToQueue('hide', null, null);
            } else {
                l.hide(args);
            }
        }
        return this;
    },
    next: function (delay) {
        var stuff = this.getNextInQueue(),
            delay = delay || 1000;
        if (stuff) {
            this.nextTimeout = setTimeout(function () {
                this.get()[stuff.showHide](stuff.content, stuff.args);
            }.bind(this), delay);
        }
        return this;
    },
    get: function () {
        return this._getCurrent();
    },
    addEvent: function (e, fn) {
        this.get().addEvent(e, fn);
        return this;
    },
    addEvents: function (es) {
        this.get().addEvents(es);
        return this;
    },
    removeEvent: function (e, fn) {
        this.get().removeEvent(e, fn);
        return this;
    },
    removeEvents: function (e) {
        this.get().removeEvents(e);
        return this;
    },
    addToQueue: function (showHide, content, args) {
        this.queue.push({
            showHide: showHide,
            content: content,
            args: args
        });
        return this;
    },
    getNextInQueue: function () {
        var n = this.queue[0] || null;
        this.queue.splice(0, 1);
        return n;
    },
    eraseQueue: function () {
        this.queue = [];
        return this;
    },
    cancel: function () {
        this.eraseQueue();
        clearTimeout(this.nextTimeout);
        return this;
    },
    determineContentType: function (content) {
        var type = 'iframe';
        if (content === null || typeof content === 'undefined') {
            type = 'empty';
        } else if ($type(content) === 'string') {
            if (content.match('#') || content.match(/(\s|\t|\n|\r)/) || !content.match(/(http|\.)/)) {
                type = 'html';
            } else if (content.match(/(.jpg|.gif|.png|.bmp)/)) {
                type = 'image';
            } else {
                type = 'iframe';
            }
        } else if ($type(content) === 'element') {
            type = 'html';
        }
        return type;
    },
    _setCurrent: function (layer) {
        this._current = layer;
        return this;
    },
    _getCurrent: function () {
        return this._current;
    }
};
DJR.Layer.Chrome = new Class({
    Extends: DJR.Chrome,
    Implements: [DJR.IFillable, DJR.IToggleable, DJR.IResizable],
    margins: {
        top: 30,
        left: 30
    },
    defaultContentSize: {
        width: 600,
        height: 400
    },
    closers: null,
    visible: false,
    initialize: function (el, measureEl) {
        this.parent(el);
        this.initFillable();
        this.initToggleable();
        this.initResizable();
        this.initCustomEvent('closeClick');
        this.initCloseEvents();
        this.initTransitions();
        this.addEvents({
            'beforeShow': function () {
                if (this.contentType !== 'iframe') {
                    this.hideContent();
                }
            }.bind(this),
            'afterShow': function () {
                if (this.contentType !== 'iframe') {
                    this.fill();
                }
                if (this.contentType !== 'empty') {
                    this.showContent();
                }
                this.fillTitle();
                this.showTitle();
            }.bind(this),
            'beforeHide': function () {
                this.removeScroll();
                this.cancel();
                this.hideContent(false);
                this.hideTitle();
                this.hideCloseButtons();
            }.bind(this),
            'afterHide': function () {
                this.cleanup();
            }.bind(this)
        });
        if (measureEl) {
            this.measureEl = measureEl;
        } else {
            this.measureEl = el;
        }
        this.cleanup();
    },
    initCloseEvents: function (el) {
        if (el) {
            var c = el.getElements('.layer_close');
            c.removeEvents('click');
            c.addEvent('click', function () {
                this.invokeEvent('closeClick');
            }.bind(this));
        } else {
            this.closers = this.el.getElements('.layer_close');
            this.closers.addEvent('click', function () {
                this.invokeEvent('closeClick');
            }.bind(this));
        }
        return this;
    },
    prepare: function (args) {
        args.closable ? (this.showCloseButtons()) : (this.hideCloseButtons());
        this.removeScroll();
        DJR.Layer.Chrome.Strategy.Prepare[args.type].call(this, args);
        this.setTitle(args.title);
        return this;
    },
    hideCloseButtons: function () {
        this.closers.each(function (closer) {
            closer.setStyle('visibility', 'hidden');
        });
        return this;
    },
    showCloseButtons: function () {
        this.closers.each(function (closer) {
            closer.setStyle('visibility', 'visible');
        });
        return this;
    },
    cleanup: function () {
        this.contentWrapper.setStyles({
            overflow: 'hidden',
            height: ''
        });
        this.contentHolder.setStyles({
            overflow: '',
            width: '',
            height: '',
            visibility: 'hidden'
        });
        this.el.setStyles({
            width: '',
            left: '',
            top: ''
        });
        this.empty();
    }
});
DJR.Layer.Chrome.Strategy = {
    Prepare: {
        empty: function (args) {
            var v = {},
                w = this.defaultContentSize.width,
                h = this.defaultContentSize.height,
                toggle = typeof args.toggleStrategy !== 'undefined' ? args.toggleStrategy : typeof args.initialBase !== 'undefined' ? 'growBaseToCenter' : 'growCenterToCenter';
            this.contentType = 'empty';
            this.setContentSize(w, h);
            DJR.Layer.Chrome.Strategy.setUpToggle.run([w, h, toggle, args], this);
        },
        html: function (args) {
            var v = {};
            var w = typeof args.contentSize !== 'undefined' ? (args.contentSize.width || 'auto') : 'auto',
            h = typeof args.contentSize !== 'undefined' ? (args.contentSize.height || 'auto') : 'auto',
            toggle = typeof args.toggleStrategy !== 'undefined' ? args.toggleStrategy : typeof args.initialBase !== 'undefined' ? 'growBaseToCenter' : 'growCenterToCenter';
            var potential = this.getPotentialSize(w, h);
            this.setContentSize(w, h);
            DJR.Layer.Chrome.Strategy.setUpToggle.run([potential.element.width, potential.element.height, toggle, args], this);
        },
        image: function (args) {
            var v = {},
                w, h, toggle = typeof args.toggleStrategy !== 'undefined' ? args.toggleStrategy : typeof args.initialBase !== 'undefined' ? 'growBaseToCenter' : 'growCenterToCenter';
            var me = this;
            var c = new Asset.image(args.content, {
                onload: function () {
                    me.setContent(this);
                    me.setTitle(args.title);
                    me.invokeEvent('onContentLoad');
                    var dims = this.getProperties('width', 'height');
                    w = dims.width.toInt();
                    h = dims.height.toInt();
                    var potential = me.getPotentialSize(w, h);
                    me.setContentSize(w, h);
                    DJR.Layer.Chrome.Strategy.setUpToggle.run([potential.element.width, potential.element.height, toggle, args], me);
                    me.show();
                }
            });
        },
        iframe: function (args) {
            var v = {},
                w, h, toggle = typeof args.toggleStrategy !== 'undefined' ? args.toggleStrategy : typeof args.initialBase !== 'undefined' ? 'growBaseToCenter' : 'growCenterToCenter';
            var me = this;
            var theframe = DJR.IFrameManager.create({
                path: args.content,
                load: function (doc, win) {
                    var sameDomain = false,
                        thebody, back, holder;
                    try {
                        if (doc.getElement('body')) {
                            sameDomain = true;
                        }
                    } catch(e) {}
                    if (sameDomain) {
                        thebody = doc.getElement('body');
                        holder = doc.getElement('#layer_holder');
                        back = doc.getElement('#layer_back');
                        if (back) {
                            back.setStyle('display', 'none');
                        }
                    }
                    var w = me.defaultContentSize.width,
                        h = me.defaultContentSize.height;
                    if (holder) {
                        var wh = holder.getStyles('width', 'height');
                        if (wh.width) {
                            w = wh.width.toInt();
                        }
                        if (wh.height) {
                            h = wh.height.toInt();
                        }
                    }
                    me.invokeEvent('onContentLoad');
                    var potential = me.getPotentialSize(w, h);
                    me.setContentSize(w, h);
                    this.setStyles({
                        width: w,
                        height: h
                    });
                    DJR.Layer.Chrome.Strategy.setUpToggle.run([potential.element.width, potential.element.height, toggle, args], me);
                    me.show();
                }
            });
            var och = function () {
                this.fillContent(theframe);
                this.removeEvent('onContentHide', och);
            }.bind(this);
            this.addEvent('onContentHide', och);
            this.hideContent();
        }
    },
    setUpToggle: function (w, h, toggle, args) {
        var verticalPadding = this.padding.top + this.padding.bottom;
        v = DJR.Layer.Chrome.Strategy.Toggle[toggle](args.initialBase, {
            width: w,
            height: h - verticalPadding,
            wrapperHeight: h - verticalPadding
        });
        var fittedSize = DJR.Measure.fitToWindow(v.endWidth, v.endHeight + verticalPadding, v.endLeft, v.endTop, 20, 20, 20);
        if (fittedSize.correction) {
            v = DJR.Layer.Chrome.Strategy.Toggle[toggle](args.initialBase, {
                width: w + 17,
                height: fittedSize.height,
                wrapperHeight: fittedSize.height - verticalPadding
            });
            v.endLeft = fittedSize.x;
            var as = function () {
                this.addScroll();
                this.removeEvent("afterShow", as);
            };
            this.addEvent("afterShow", as);
        }
        this.updateTransitions(v);
    },
    Toggle: {
        growBaseToCenter: function (base, args) {
            base = $(base);
            var baseCenter = base.getAllDimensions().centerPoint,
                endCoords = DJR.Measure.getCenterCoords(args.width, args.height);
            return {
                startTop: baseCenter.y,
                startLeft: baseCenter.x,
                startWidth: 0,
                startHeight: 0,
                startWrapperHeight: 0,
                endTop: endCoords.y,
                endLeft: endCoords.x,
                endWidth: args.width,
                endHeight: args.height,
                endWrapperHeight: args.wrapperHeight
            };
        },
        growCenterToCenter: function (base, args) {
            var startCoords = DJR.Measure.getWindowCenter();
            endCoords = DJR.Measure.getCenterCoords(args.width, args.height);
            return {
                startTop: startCoords.y,
                startLeft: startCoords.x,
                startWidth: 0,
                startHeight: 0,
                startWrapperHeight: 0,
                endTop: endCoords.y,
                endLeft: endCoords.x,
                endWidth: args.width,
                endHeight: args.height,
                endWrapperHeight: args.wrapperHeight
            };
        },
        centerToCenter: function (base, args) {
            var coords = DJR.Measure.getCenterCoords(args.width, args.height);
            return {
                startTop: coords.y,
                startLeft: coords.x,
                startWidth: args.width,
                startHeight: args.height,
                startWrapperHeight: args.wrapperHeight,
                endTop: coords.y,
                endLeft: coords.x,
                endWidth: args.width,
                endHeight: args.height,
                endWrapperHeight: args.wrapperHeight
            };
        }
    }
};


DJR.Templates = {};
DJR.Templates.Html = {};
DJR.Templates.Html.Layers = {
    DEFAULT: '<div class="layer T:53 R:8 B:8 L:8"><div style="padding:15px;"><h2 class="DJR_title"></h2><a href="javascript:void(0);" class="layer_close">Close X</a><div style="clear:both;"></div></div><div style="visibility:hidden;" class="DJR_content"></div></div>'
};
DJR.Bootstrapper = {};
DJR.Bootstrapper.Parser = {
    parse: function (str, namespace, defaults) {
        var reGroup = /(?:\w|\d)*\:\:(\w|\d|\:)[^ ]*/g,
            reValues = /((?:\w|\d)[^:]*):((?:\w|\d)[^:]*)/g,
            reGetNamespace = /((?:\w|\d)*)\:\:/,
            reIsInteger = /^\d*$/,
            tempRe = null,
            match = null,
            namespace = namespace || null,
            tests = [],
            results = {};
        if (namespace !== null) {
            tempRe = new RegExp(namespace + "\:\:.[^ ]*");
            tests[0] = tempRe.exec(str);
        } else {
            while (match = reGroup.exec(str)) {
                tests.push(match[0]);
            }
        }
        if (tests.length == 1) {
            var test = tests[0],
                ns = reGetNamespace.exec(test),
                res = results;
            while (match = reValues.exec(test)) {
                if (reIsInteger.test(match[2])) {
                    match[2] = match[2].toInt();
                } else if (match[2] === 'true' || match[2] === 'false') {
                    match[2] = (match[2] === 'true') ? true : false;
                }
                res[match[1]] = match[2];
            }
        } else {
            tests.each(function (test) {
                var ns = reGetNamespace.exec(test),
                    res = results[ns[1]] = {};
                while (match = reValues.exec(test)) {
                    if (reIsInteger.test(match[2])) {
                        match[2] = match[2].toInt();
                    } else if (match[2] === 'true' || match[2] === 'false') {
                        match[2] = (match[2] === 'true') ? true : false;
                    }
                    res[match[1]] = match[2];
                }
            });
        }
        for (var d in defaults) {
            if (defaults.hasOwnProperty(d)) {
                if (typeof results[d] === 'undefined') {
                    results[d] = defaults[d];
                }
            }
        }
        return results;
    }
};
DJR.Bootstrapper.Layers = {
    init: function () {
        var layer_triggers = new DJR.Trigger($$('[class*=layerLauncher::]'), {
            click: function () {
                var v = DJR.Bootstrapper.Layers.parse(this);
                v.contentSize = {
                    width: v.width,
                    height: v.height
                };
                DJR.Layer.Manager.show(v.content, v);
            }
        });
    },
    parse: function (trigger) {
        var results = DJR.Bootstrapper.Parser.parse(trigger.get('class'), 'layerLauncher', {
            toggleStrategy: 'growBaseToCenter',
            chrome: 'default',
            clone: false,
            closable: true,
            useLoader: true,
            base: trigger,
            title: trigger.get('title'),
            content: trigger.get('href')
        });
        return results;
    }
}

DJR.Bootstrapper.Templates = {};
DJR.Bootstrapper.Templates.Html = {
    init: function (obj) {
        if (obj && $type(obj) === 'object') {
            DJR.Bootstrapper.Templates.Html.inject(obj);
        } else if (typeof DJR.Bootstrapper.Templates.Html !== 'undefined') {
            DJR.Bootstrapper.Templates.Html.inject(DJR.Templates.Html);
        }
    },
    inject: function (obj) {
        for (var item in obj) {
            if ($type(obj[item]) === 'string') {
                var dom = obj[item].makeDom(),
                    pl_wrapper = new Element('div', {
                    'class': 'pl'
                });
                obj[item] = dom.getFirst();
                DJR.Utils.body.adopt(pl_wrapper);
                pl_wrapper.adopt(obj[item]);
                var measure = pl_wrapper.clone();
                DJR.Utils.body.adopt(measure);
                obj[item + "_MEASURE"] = measure.getFirst();
                dom.destroy();
            } else if ($type(obj[item]) === 'object') {
                DJR.Bootstrapper.Templates.Html.init(obj[item]);
            } else if ($type(obj[item]) === 'element') {
                return;
            } else {
                throw new Error('the HtmlTemplates are not setup correctly');
            }
        }
    }
};
DJR.Bootstrapper.Overlay = {
    init: function (args) {
        DJR.Utils.overlay = new DJR.Overlay(args);
    }
};
DJR.Bootstrapper.BackgroundCache = {
    init: function () {
        if (Browser.Engine.trident4) {
            try {
                document.execCommand("BackgroundImageCache", false, true);
            } catch(err) {}
        }
    }
};
DJR.Bootstrapper.Initializer = {
    init: function () {
        window.addEvent('domready', function () {
            DJR.Bootstrapper.Templates.Html.init();
            DJR.Bootstrapper.BackgroundCache.init();
            DJR.Bootstrapper.Overlay.init();
            DJR.Layer.Manager.init();
            DJR.Bootstrapper.Layers.init();
        });
    }
};
DJR.Bootstrapper.Initializer.init();