﻿var BOX = {};

(function($) {


var W = this, D = this.document;
var html = $(D.documentElement || 'html');

var fnEmpty = function() {};
var onLoadIsDone = false;
BOX.onLoadIsDone = false;

$(W).load(function() {
    onLoadIsDone = true;
    BOX.onLoadIsDone = true;
});

// for in filter
var isOwnProperty = function(o, p) {
    return typeof o.constructor.prototype[p] == 'undefined';
};

BOX.isOwnProperty = isOwnProperty;

// get datas from HTML classes, eg. class="box:id:signOut"
var getStoreId = function(el, type) {
    type = type || 'id';
    var re = new RegExp('box:' + type + ':(\\S+)');
    if (el.className && el.className.indexOf('box:' + type + ':') > -1) {
        var store = el.className.match(re);
        if (store && store.length == 2) {
            return store[1];
        }
    }
    return null;
};

BOX.getStoreId = getStoreId;

// extend a class
BOX.extend = function(sb, sp, members) {
    function addToPrototype(o) {
        for (var m in o) {
            if (isOwnProperty(o, m)) {
                sb.prototype[m] = o[m];
            }
        }
    }
    
    if (typeof sp == 'object') {
        addToPrototype(sp);
    } else {
        var F = function() {};
        F.prototype = sp.prototype;
        sb.prototype = new F();
        sb.prototype.constructor = sb;
        sb.superclass = sp.prototype;
        if (sp.prototype.constructor == Object.prototype.constructor) {
            sp.prototype.constructor = sp;
        }
        
        if (typeof members == 'object') {
            addToPrototype(members);
        }
    }
};

// Observable Class
BOX.Observable = function() {
    this.listeners = {};
};
BOX.Observable.prototype = {
    addEvents: function(events, listeners) {
        for (var i = 0, len = events.length; i < len; i++) {
            this.listeners[events[i]] = [];
        }
        if (typeof listeners == 'object') {
            for (var l in listeners) {
                if (isOwnProperty(listeners, l)) {
                    this.addListener(l, listeners[l].fn, listeners[l].scope);
                }
            }
        }
    },
    
    fireEvent: function(eventName) {
        if (typeof eventName == 'string') {
            var eventParts = eventName.split('.'), eplen = eventParts.length, epi = 0, partialEventName = '';
            var args = [{owner: this}];
            if (arguments.length > 1) {
                args = args.concat(Array.prototype.slice.call(arguments, 1));
            }
            if (eplen > 1) {
                args[0].namespace = eventName.replace(/^[^.]+\./, '').split('.');
            }
            for (; epi < eplen; epi++) {
                partialEventName += (partialEventName ? '.' : '') + eventParts[epi];
                var ls = this.listeners[partialEventName], len, li, i = 0;
                if (ls && (len = ls.length)) {
                    args[0].type = partialEventName;
                    for (; i < len; i++) {
                        li = ls[i];
                        li.fn.apply(li.scope, args);
                    }
                }
            }
        }
    },
    
    addListener: function(eventName, fn, scope) {
        if (!this.listeners[eventName]) {
            this.listeners[eventName] = [];
        }
        scope = scope || this;
        if (this.hasListener(eventName, fn, scope) == -1) {
            this.listeners[eventName].push({fn: fn, scope: scope});
        }
        return this;
    },
    
    addListeners: function(listeners) {
        if (typeof listeners == 'object') {
            for (var l in listeners) {
                if (isOwnProperty(listeners, l)) {
                    this.addListener(l, listeners[l].fn, listeners[l].scope);
                }
            }
        }
        return this;
    },
    
    removeListener: function(eventName, fn, scope) {
        if (this.listeners[eventName]) {
            scope = scope || this;
            var i;
            if ((i = this.hasListener(eventName, fn, scope)) > -1) {
                this.listeners[eventName].splice(i, 1);
            }
        }
        return this;
    },
    
    removeListeners: function(listeners) {
        if (typeof listeners == 'object') {
            for (var l in listeners) {
                if (isOwnProperty(listeners, l)) {
                    this.removeListener(l, listeners[l].fn, listeners[l].scope);
                }
            }
        }
        return this;
    },
    
    purgeListeners: function(eventName) {
        if (typeof eventName == 'string') {
            this.listeners[eventName] = [];
        } else {
            this.listeners = {};
        }
        return this;
    },
    
    hasListener: function(eventName, fn, scope) {
        scope = scope || this;
        var ls = this.listeners[eventName], len = ls.length, l, i = 0;
        for (; i < len; i++) {
            l = ls[i];
            if (l.fn == fn && l.scope == scope) {
                return i;
            }
        }
        return -1;
    }
};

// get page and viewport dimensions
var getDimensions = function() {
    var de = D.documentElement;
    return {
        'viewportW': $(W).width(),
        'viewportH': $(W).height(),
        'scrollW': W.pageXOffset || (de && de.scrollLeft) || D.body.scrollLeft,
        'scrollH': W.pageYOffset || (de && de.scrollTop) || D.body.scrollTop,
        'totalW': de.scrollWidth || W.body.scrollWidth,
        'totalH': de.scrollHeight || W.body.scrollHeight
    };
};
BOX.getDimensions = getDimensions;

})(jQuery);

