﻿//hmsa namespace
var hmsa = function() {
    //private   
    
    //public
    return {
        extend: function() {
            var target = arguments[0], a = 1;
            
            if(arguments.length == 1) {
                target = this;
                a = 0;
            }
            
            var prop;
            while(prop = arguments[a++])
                for(var i in prop) target[i] = prop[i];
                
            return target;
        }
    };
}();

//events namespace
hmsa.extend({
    events: new function() {
        //store all registered event handlers so we can remove them on unload, due to ie memory leaks
        var _allHandlers = [];
        
        //to store functions to be called when DOM loads
        var _initHandlers = [];
              
        //private callback for when DOM is loaded
        var _initCallback = function(){           
            hmsa.events.ready = true;
            
            //execute all waiting handlers
            if(_initHandlers) {             
                for(var index = 0; index < _initHandlers.length; index++) {
                    _initHandlers[index]();
                }
                _initHandlers = null;
            }
            
            //unbind event
            if(document.removeEventListener)
                document.removeEventListener("DOMContentLoaded", _initCallback, false);
        };
        
        //bind DOM loaded event
        if(document.addEventListener) {
            document.addEventListener("DOMContentLoaded", _initCallback, false);
        }
        else {
            //ie doesn't support DOMContentLoaded
            //used variation of http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
            
            document.write("<scr" + "ipt id=\"ie_init\" defer=\"true\" " + "src=\"//:\"><\/script>");
	
	        var script = document.getElementById("ie_init");
	                	
	        if(script) {
		        script.onreadystatechange = function() {
			        if(this.readyState != "complete")
			            return;
			            
			        this.parentNode.removeChild(this);
			        _initCallback();
		        };
            }
		    	        
	        script = null;
        }
        
        //public methods & properties
        return {
            ready: false,            
            bind: function(elem, ev, handler){
                if(!ev || !handler || ev == "")
                    return;

                elem = (elem) ? elem : document;

                if(ev == "init" || ev == "DOMContentLoaded"){
                    if(hmsa.events.ready)
                        handler();                      //DOM already loaded execute now
                    else
                        _initHandlers.push(handler);    //store function to call when DOM loads
                   
                    return null;
                }else{
                    var handlerFN = handler;
                    
                    if(elem.attachEvent) {
                        handlerFN = function(){
                            handler(window.event);
                        }
                        elem.attachEvent("on" + ev, handlerFN);
                    } else if(elem.addEventListener) { //moz, opera                       
                        elem.addEventListener(ev, handlerFN, true);
                    }
                    
                    var ev = {
                        element: elem,
                        name: ev,
                        handler: handlerFN
                    };
                    
                    //add to event handler array
                    _allHandlers.push(ev);
                
                    return ev;
                }                
            },
            unbind: function(ev) {
                var elem = ev.element;
                
                if(elem.detachEvent)
                    elem.detachEvent("on" + ev.name, ev.handler);
                else if(elem.removeEventListener)
                    elem.removeEventListener(ev.name, ev.handler, true);
                    
                //remove event handler array
                for(var index = 0; index < _allHandlers.length; index++) {
                    if(_allHandlers[index] == ev) {
                        _allHandlers.splice(index, 1);
                        break;
                    }
                }            
            },
            unbindall: function(){
                while(_allHandlers.length > 0)
                    hmsa.events.unbind(_allHandlers[0]);
            }
        };
    }
});

//query
hmsa.extend({
    query: new function() {
        return {
            getElementsByClass: function(className, tagName, obj){
                obj = (!obj) ? document : obj;
                tagName = (!tagName) ? "*" : tagName;

                var elements = obj.getElementsByTagName(tagName);
                var matches = new Array();
                var regex = new RegExp("(^|\\s)" + className + "(\\s|$)");
                var element;

                for(var i = 0; i < elements.length; i++){                    
                    element = elements[i];
                    if(regex.test(element.className))
                        matches.push(element);
                }

                return matches;
            }
        };
    }
});

//browser capabilities
hmsa.extend({
    browser: new function() {
        var ua = navigator.userAgent.toLowerCase();
        
        return {
            safari: /webkit/.test(ua),
		    opera: /opera/.test(ua),
		    msie: /msie/.test(ua) && !/opera/.test(ua),
		    mozilla: /mozilla/.test(ua) && !/(compatible|webkit)/.test(ua)
        };
    }
});

//cookies
hmsa.extend({
    cookies: new function() {
        return {
            getCookie: function(key){
                var nameEQ = key + "=";
	            var ca = document.cookie.split(';');
	            
	            for(var i = 0; i < ca.length; i++){
		            var c = ca[i];
		            
		            //trim spaces
		            while(c.charAt(0)==' ')
		                c = c.substring(1, c.length);
		                
		            if(c.indexOf(nameEQ) == 0) 
		                return c.substring(nameEQ.length, c.length);
	            }
	            
	            return null;
            },
            setCookie: function(key, value, days, domain){
                var cookie = key + "=" + value;

                if(days){
                    var date = new Date();
                    date.setTime(date.getTime()+(days*24*60*60*1000));
                    cookie += "; expires=" + date.toGMTString();
                }

                cookie += "; path=/";

                if(domain)
                    cookie += "; domain=" + domain;

                document.cookie = cookie;
            },
            removeCookie: function(key){
                setCookie(key, "", -1);
            }
        };
    }
});

//DOM
hmsa.extend({
    dom: new function(){
        return {            
            insertAfter: function(elem, after){
                if(after.parentNode && after.nextSibling)
                    after.parentNode.insertBefore(elem, after.nextSibling);
            },
            remove: function(elem){
                if(elem.parentNode)
                    elem.parentNode.removeChild(elem);
            },
            createObjectParameter: function(nodeObject, sName, sValue){
                var n = document.createElement("param");
                n.setAttribute("name", sName);	
                n.setAttribute("value", sValue);
                nodeObject.appendChild(n);
            }
        };
    }
});

//flash
hmsa.extend({
    flash: new function(){
        var wroteIEScript = false;
        var flashVersion = null;
        
        return {
            hasFlash: function(version){
                if(version == null)
                    version = 8;
            	
            	if(hmsa.browser.msie){
            	    if(!wroteIEScript){
            	        document.write('<script language="VBScript"\> \non error resume next \nhasFlash = (IsObject(CreateObject("ShockwaveFlash.ShockwaveFlash." & ' + version + '))) \n</script\> \n');
            	        wroteIEScript = true;
            	    }
            	    
            	    if(window.hasFlash != null)
                        return window.hasFlash;
	            }

	            if(navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"] && navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin){
		            var flashDescription = (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]).description;
		            
		            var start = flashDescription.indexOf("Flash ") + 5;
		            var end = flashDescription.indexOf(".");
		            return parseInt(flashDescription.substring(start, end)) >= version;
	            }
            	
	            return false;
            },         
            swf: function(movie, width, height){
                var _movie = movie;
                var _attributes = new Array();
                var _variables = new Array();
                var _parameters = new Array();
                var _fallback = null;
 
                //init
                _attributes["type"] = "application/x-shockwave-flash";
                if(width)
                    _attributes["width"] = width;
                if(height)
                    _attributes["height"] = height;

                return {
                    setFallback: function(id){
                        _fallback = id;
                    },
                    getFallback: function(){
                        return _fallback;
                    },
                    setAttribute: function(name, value){
                        _attributes[name] = value;
                    },
                    getAttribute: function(name){
                        return _attributes[name];
                    },
                    setVariable: function(name, value){
                        _variables[name] = value;
                    },
                    getVariable: function(name){
                        return _variables[name];
                    },
                    setParameter: function(name, value){
                        _parameters[name] = value;
                    },
                    getParameter: function(name){
                        return _parameters[name];
                    },
                    getMovie: function(){
                        var movie = _movie + "?";
                        for(var name in _variables)
                            movie += name + "=" + _variables[name] + "&";
                        return movie.substr(0, movie.length - 1);
                    },
                    getHTML: function(){
                        var movie = this.getMovie();
                        var html = "<object data=\"" + movie + "\"";

                        for(var name in _attributes)
                            html += " " + name + "=\"" + _attributes[name] + "\"";

                        html += ">\n"

                        for(var name in _parameters)
                            html += "<param name=\"" + name + "\" value=\"" + _parameters[name] + "\" />\n";

                        html += "<param name=\"movie\" value=\"" + movie + "\" />\n";
                        
                        if(_fallback != null){
                            var obj = document.getElementById(_fallback);
                            html += obj.innerHTML;
                        }
                        
                        html += "</object>";

                        return html;
                    },
                    embed: function(elem){                        
                        if(elem && typeof elem.innerHTML != "undefined")
                            elem.innerHTML = this.getHTML();
                    }                    
                }
            }
        };
    }
});

//css
hmsa.extend({
    css: new function(){
        return {            
            hasStyle: function(elem, style){
                return (elem.className.indexOf(style) != -1)
            },
            addStyle: function(elem, style){
                if(!hmsa.css.hasStyle(elem, style)){
                    if(!elem.className || elem.className.length == 0)
                        elem.className = style;
                    else
                        elem.className += " " + style;
                }                    
            },
            removeStyle: function(elem, style){
                elem.className = (elem.className == style) ? "" : elem.className.replace(style, "");
            },
            swapStyles: function(elem, oldStyle, newStyle){
                if(hmsa.css.hasStyle(elem, oldStyle))
                    elem.className = elem.className.replace(oldStyle, newStyle);
                else
                    addStyle(elem, newStyle);
            }
        };
    }
});

//string
hmsa.extend({
    string: new function(){
        return {            
            trim: function(string){
                return string.replace(/^\s+|\s+$/g, '');
            },
            ltrim: function(string){
                return string.replace(/^\s+/g, '');
            },
            rtrim: function(string){
                return string.replace(/\s+$/g, '');
            },
            normalize: function(string){
	            return string.replace(/\s+/g, " ");
            }
        };
    }
});

hmsa.extend({
    utility: new function(){
        return {            
            escapeHex: function(sHex){
                if(hmsa.browser.msie){
                    /* The RegExp for IE breaks old Gecko's, the RegExp for non-IE breaks IE 5.01 */
			        return sHex.replace(new RegExp("%\d{0}", "g"), "%25");
		        }
		        return sHex.replace(new RegExp("%(?!\d)", "g"), "%25");
		    }
        };
    }
});

//shorcuts
String.prototype.trim = function(){ return hmsa.string.trim(this); }
String.prototype.ltrim = function(){ return hmsa.string.ltrim(this); }
String.prototype.rtrim = function(){ return hmsa.string.rtrim(this); }
String.prototype.normalize = function(){ return hmsa.string.normalize(this); }

function $(){
    var elements = new Array();
	for (var i = 0; i < arguments.length; i++) {
		var element = arguments[i];
		if (typeof element == 'string')
			element = document.getElementById(element);
		if (arguments.length == 1)
			return element;
		elements.push(element);
	}
	return elements;
}

function $$(){
    var elements = new Array();
	for (var i = 0; i < arguments.length; i++) {
		var element = arguments[i];
		if (typeof element == 'string')
			element = hmsa.query.getElementsByClass(element);
		if (arguments.length == 1)
			return element;
		elements.push(element);
	}
	return elements;
}