/* vim: set expandtab tabstop=4 shiftwidth=4: */
// This is the file users point to.
// This file will live on the CDN

///
/// Launchpad Public Functions
///

if (typeof $Launchpad == "undefined") {

    var $Launchpad = {
        CreateMenu : function (options) {
        	
            options.debug && ($ClearspringDebugEnabled = true);
            options.actionElement = document.getElementById(options.actionElement) || options.actionElement;
            
            if (options.actionElement && typeof options.actionElement  != "object") {
                setTimeout($LaunchpadUtil.bind(this.CreateMenu, this, [options]), 40);
                return { 
                    error : "Incorrect Launchpad Usage: \nIf you use actionElement then you do not need to use the onclick event.",
                    toggle : function(evt) { alert(this.error); return false;},
                    show : function(evt) { alert(this.error); return false;},
                    hide : function(evt) { alert(this.error); return false;}};
            }
            
            if (options.actionElement && !options.actionElement.Menu) {
                var ButtonObj = new $LaunchpadButton(options);
                options.actionElement.Menu = ButtonObj.Menu;
                return ButtonObj;
            }
            
            if (options.actionElement) { 
                return options.actionElement.Menu; 
            }
            
            return new $LaunchpadMenu(options);
        },

        ShowButton : function (options) {
            options.debug && ($ClearspringDebugEnabled = true);
            
            if (options.actionElement) {
                return this.CreateMenu(options);
            } else {
                return new $LaunchpadButton(options);
            }
        },

        ShowMenu : function (options) {
            options.debug && ($ClearspringDebugEnabled = true);

            if (!options.actionElement) {
                options.inline = !options.targetElement;
                options.show = true;
                return new $LaunchpadMenu(options);
            } else {
                options.show = true;
                return this.CreateMenu(options);
            }
        }
    };
}
///
/// Debug
///

if (typeof $ClearspringDebug == "undefined")
{

    var $ClearspringDebugEnabled = false;

    function $ClearspringDebug(a, b)
    {
        if ($ClearspringDebugEnabled)
        {
            if( (window.console !== undefined) && (console.log !== undefined) && (typeof(console.log) === "function") )
            { 
                if( b !== undefined )
                { 
                    console.log(a,b); 
                } 
                else
                { 
                    console.log(a); 
                } 
            }
        }
    }
}


/* vim: set expandtab tabstop=4 shiftwidth=4: */

// This is the file users point to.
// This file will live on the CDN

///
/// Button related analytics.  These functions will directly create .png requests to send tracking information
///
if (typeof $LaunchpadAnalytics == "undefined") {
	
    /*
     Callback called by menu to finish initialization after session created
     and available
     @todo add to flash menu
    */
    function $ClearspringLaunchpadInit(options) {
        var callback = window.ClearspringLaunchpadInitCallbacks.pop();
        callback(options);
    }

    /*
     Class representing Launchpad usage with things related to the page, not the menu itself
     @todo wrap a flash bug
    */
    function $LaunchpadAnalytics(options, callback) {
        this.button = {
            load :          { code : 0x60,  type : 0x1 },
            firstClick :    { code : 0x51,  type : 0x1 }, 
            click :         { code : 0x152, type : 0x1 } 
        };

        this.init = function(options, callback) {
            this.options = options;

            window.ClearspringLaunchpadInitCallbacks = window.ClearspringLaunchpadInitCallbacks || [];
            window.ClearspringLaunchpadInitCallbacks.push(callback);

            // support woth widgetId or wid in calling menu
            this.options.wid = this.options.wid || this.options.widgetId || false;
            
            /*
             deprecated?
             */
            var querystring = this.options.wid ? 
                "wid=" + this.options.wid : 
                "userId=" + encodeURIComponent(this.options.userId) + "&widgetName=" + encodeURIComponent(this.options.widgetName); 
            
            var script = document.createElement('script'); 
            script.type = 'text/javascript'; 
            script.src = this.options.initURL + "?" + querystring;

            var head = document.getElementsByTagName('head')[0]; 
            head.appendChild(script);
        };
        
        this.track = function(options) {
            $ClearspringDebug("JS Bug tracking code: 0x" + options.code.toString(16) + ", type: 0x" + options.type.toString(16));
            
            if (this.kernel) {
                this.kernel._cs_6('trk', options.code.toString(16), options.type.toString(16));
            } else {
                $ClearspringDebug("kernel not loaded.");
            }
        };
    
        setTimeout($LaunchpadUtil.bind(this.init, this, [options, callback]), 40);
    }
}/* vim: set expandtab tabstop=4 shiftwidth=4: */

/**
 * Launchpad Private Class
 *
 * @author dylan
 * @author rajat
 * @author mjk
 * @author tim
 *
 * @version $Id$
 */

if (typeof $LaunchpadObject == "undefined") {
	
    var $LaunchpadObject = {
        getOptions : function() {
            
            return {
                menuWidth : 400,
                menuHeight : 240,
                env : "clearspring.com/",
                cdn : "http://cdn.clearspring.com/launchpad/v2/3940/",
                initURL : "http://widgets.clearspring.com/launchpad/init.js",
                dummywid : "475db72337b302d4",
                unique : false,
                invalidConfiguration : false
            };
        },

        getURL : function (wid, settings) {
        	
            var name = escape(settings.widgetName);
            var uid = settings.userId;
            var w = settings.menuWidth;
            var h = settings.menuHeight;
            var emw = settings.width || settings.widgetWidth;
            var emh = settings.height || settings.widgetHeight;
            
            if (w > 800) w = 800;
            else if (w < 160) w = 160;

            if (h > 800) h = 800;
            else if (h < 150) h = 150;

            var widSize = '';
            if (emw && emh) widSize = '/-EMW/'+emw+'/-EMH/'+emh;
            
            var dummywid = settings.dummywid;

            settings._cs_lpop = 1;
            //settings.cachebuster= $LaunchpadUtil.random();
            if (settings.sources != null || settings.unique === true || (!settings.userId && !wid))
            {
                 //if there are sources then the source must be unque
                settings._cs_unique = 1;
            }
            if (!wid && !settings.source && !settings.sources) settings._cs_cnf_err = 1;

            delete settings.noDocumentWrite;

            var simpleSettings = {};
            for (var k in settings) simpleSettings[k] = settings[k];
            
            var worthless = ['source', 'sources', 'unique', 'invalidConfiguration', 'wid', 'cdn', 'initURL'];
            for (var i = 0; i < worthless.length; i++) {
                if (simpleSettings[worthless[i]]) { 
                    delete simpleSettings[worthless[i]];
                }
            }
            simpleSettings.env = simpleSettings.env.substr(0, simpleSettings.env.length - 1);

            var args = {};
            try {
                var src = window.location.search;
                src.replace(
                        new RegExp( "([^?=&]+)(=([^&]*))?", "g" ),

                        // For each matched query string pair, add that
                        // pair to the URL struct using the pre-equals
                        // value as the key.
                        function( $0, $1, $2, $3 ){
                            args[ $1 ] = $3;
                        });
            } catch (e) {}
            
            //Handle query string parameters
            for (var k in {_cs_pwid:''}) {
            	if (args[k]) simpleSettings[k] = args[k];
            }
            
            //Create URL
            
            var tlas = {
            	FPS : 30,
            	DXY : "0+0",
            	MXY : "0+0",
            	TRK : (settings.inColose ? 0 : 1)
            };
            if ('tlas' in simpleSettings) {
            	var o = simpleSettings['tlas'];
            	for (var k in o) tlas[k] = o[k];
            	delete simpleSettings['tlas'];
            }
            
            //Setup tlas
            if (w) tlas['MSW'] = tlas['W'] = w;
            if (h) tlas['MSH'] = tlas['H'] = h;

            //Convert tla data to string            
            var out = [];
            for (var k in tlas) {
            	out.push('-'+k);
            	out.push(tlas[k]);
            }
            var tlaData = out.join('/');
            
            var pid = '';
            if ('pid' in simpleSettings) {
            	pid = simpleSettings['pid'] || '';
            	delete simpleSettings['pid'];
            }
            
            var template = (wid?'m':'op')+'.template.v3.as3.swf';
            var path  = 'o/'+(wid?wid + (pid!=''?'/'+pid:'') : dummywid)+ '/-/' + tlaData + '/' + template;
            return 'http://widgets.' + settings.env + path + '?' + $LaunchpadUtil.toQueryString(simpleSettings);
            
        },
        
        getBlob : function (source) {
            if (!source) { return false; }
        
            var el = document.getElementById(source);
            
            if (!el || !el.tagName) { return false; }
            if (el.tagName == "TEXTAREA" && el.textLength > 8) { return el.value; }
            if (el.tagName == "OBJECT" || el.tagName == "EMBED") { 
                return "Please put a div around the item you wish to use and use the id of that div instead."; 
            }
            if (el.innerHTML && el.innerHTML.length > 8) { return el.innerHTML; }

            return false;
        }
    };
}
/* vim: set expandtab tabstop=4 shiftwidth=4: */

/**
 * Launchpad Button Class
 * 
 * @author dylan
 * @author rajat
 * @author mjk
 * @author tim
 * @version $Id$
 */
if (typeof $LaunchpadButton == "undefined") {
	
    function $LaunchpadButton(options) { 

        this.init = function(options) {
            this.options = $LaunchpadUtil.setOptions($LaunchpadObject.getOptions(), options);

            if (this.options.actionElement) {
                this.Button = document.getElementById(this.options.actionElement) || this.options.actionElement;
            } else {
                this.createButton();
            }
            this.buttonBug = new $LaunchpadAnalytics(this.options, $LaunchpadUtil.bind(this._init, this)  );
        };

        this._init = function(options) {
            this.buttonBug.track(this.buttonBug.button.load);
	        this.Menu = new $LaunchpadMenu(this.options, this.buttonBug);
            this.Menu.Button = this.Button; 
            this.addEvents();
	        $LaunchpadUtil.addEvent(this.Button, 'click', $LaunchpadUtil.bind(this.onClick, this) ) ;
        };

        this.createButton = function() { 
            //adjust button for different browsers
            var marginBottom = 
                                (navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1) ? 4 : 
                                (navigator.userAgent.indexOf('AppleWebKit/') > -1) ? -2 : 0;
        
            var buttonStyle = 'border:none; background:url(' + this.options.cdn + 'img/button-share.gif) no-repeat 0px 0px;width:80px;height:18px;margin:0px;margin-bottom:'+marginBottom+'px;overflow:hidden; outline:none; cursor:pointer; padding:0;  ';
        
	        var buttonID = "button" + $LaunchpadUtil.random();
            var button = "<button id=\"" + buttonID + "\" href=\"#\" style=\"" + buttonStyle + "\"  onclick=\"return false;\"></button>";

            if (this.options.noDocumentWrite) {
                var div = $LaunchpadUtil.create('div', { style : "display:none;" });
                div.innerHTML = button;
                document.body.appendChild(div);
            } else {
                document.write(button);
            }
        
	        this.Button = document.getElementById(buttonID);
        };
        
        this.addEvents = function() {	        
            if (!this.options.actionElement) {
                $LaunchpadUtil.addEvent(this.Button, 'mouseover', $LaunchpadUtil.bind(this.onMouseover, this) ) ;
                $LaunchpadUtil.addEvent(this.Button, 'mouseout', $LaunchpadUtil.bind(this.onMouseout, this) ) ;
                $LaunchpadUtil.addEvent(this.Button, 'mousedown', $LaunchpadUtil.bind(this.onDown, this) ) ;
            }
        };

        this.onClick = function(event) {
        	
            this.Button.blur();
            this.Menu.toggle();

            $LaunchpadUtil.stopEvent(event);
            
            if (!this.firstClick) {
                this.buttonBug.track(this.buttonBug.button.firstClick);
                this.buttonBug.track(this.buttonBug.button.click);
                this.firstClick = true;
            } else {
                this.buttonBug.track(this.buttonBug.button.click);
            }
            
            return false;
        };

        this.onMouseover = function() {
            if (this.Menu.visible) {
                this.Button.style.backgroundPosition = "0px -72px";
            } else {
                this.Button.style.backgroundPosition = "0px -18px";
            }
        };

        this.onMouseout = function () {
            if (this.Menu.visible) {
                this.Button.style.backgroundPosition = "0px -54px";
            } else {
                this.Button.style.backgroundPosition = "0px 0px";
            }
        };


        this.onDown = function () {
            if (this.Menu.visible) {
                this.Button.style.backgroundPosition = "0px -36px";
            } else {
                this.Button.style.backgroundPosition = "0px -36px";
            }
        };

        this.init(options);
    }
}/* vim: set expandtab tabstop=4 shiftwidth=4: */

if (typeof CSM == 'undefined') {
    var CSM = {};
}

/**
 * Launchpad Menu class. Mostly a wrapper for Flash. For now.
 *
 * @author dylan
 * @author rajat
 * @author mjk
 * @author tim
 *
 * @version $Id$
 */
if (typeof $LaunchpadMenu == "undefined") {

    function $LaunchpadMenu(options) {
        this.init = function(options) {
        	
            this.ready = false;
            
            this.options = $LaunchpadUtil.setOptions($LaunchpadObject.getOptions(), options);
            this.options.wid = this.options.wid || this.options.widgetId || false;
            this.options.inConsole = ('inConsole' in this.options) && this.options.inConsole.toString().toLowerCase()=='true'; 
            
            // if no wid set and no source set and no sources set, then invalid configuration
            if (!this.options.wid && !this.options.source && !this.options.sources) {
                this.options.invalidConfiguration = true;
            } else if (this.options.source && !$LaunchpadObject.getBlob(this.options.source)) {
                this.options.invalidConfiguration = true;
            } else if (this.options.source && $LaunchpadObject.getBlob(this.options.source) === "[YOUR CONTENT GOES HERE]") {
                this.options.invalidConfiguration = true;
            }
            
            this.options.menuWidth = this.options.menuWidth < 160 ? 160 : this.options.menuWidth;
            this.options.menuHeight = this.options.menuHeight < 150 ? 150 : this.options.menuHeight;

            this.options.menuWidth = this.options.menuWidth > 800 ? 800 : this.options.menuWidth;
            this.options.menuHeight = this.options.menuHeight > 800 ? 800 : this.options.menuHeight;

            this.menuID = "lpop" + $LaunchpadUtil.random();
            this.options.menuID = this.menuID;

            if (this.options.inline) {
                var html = '<div style="position: relative; width:' + this.options.menuWidth + 'px; height:' + this.options.menuHeight + ';" id="Parent'+ this.menuID +'"></div>';
                document.write(html);
            }            

            this._init(this.options);
        };
        
        this._init = function(options) {
            this.ready = true;
            this.onReadyFunction && this.onReadyFunction();
            this.options.show && this.show();

            CSM[this.options.menuID] = {close: $LaunchpadUtil.bind(this.hide, this), 
                                        cat: $LaunchpadUtil.bind(this.cat, this)}; 
        };

        this.cat = function () {
            var rv = {};
            if (this.options.config) rv.config = this.options.config;
            if (this.options.userId) rv.userId = this.options.userId;
            
            try {
                rv.sources = {};
                if (this.options.source) {
                    rv.sources.one = this.getSource(this.options.source);
                }
                if (this.options.sources)  {
                    for (var k in this.options.sources) {
                        if (k)  {
                            rv.sources[k] = this.getSource(this.options.sources[k]);
                        }
                    }
                }
            } catch (e) {
                // trouble with sucking source
            }
            return rv;
        };

        this.toggle = function() {
            if (this.visible) {
                this.hide();
            } else {
                this.show();
            }
        };

        this.hide = function() {
            if (!this.ready) {
                this.onReadyFunction = $LaunchpadUtil.bind(this.hide, this);
            } else if (this.menuParent && this.visible) {
                !this.options.actionElement && this.Button && (this.Button.style.backgroundPosition = "0px 0px");
                this.menuParent.style.height = "1000000px";
                this.menuParent.style.marginTop = "-1000000px";
                this.menuParent.style.zIndex = -1000;
                this.visible = false;
                this.callMenu('hide');                
            }
            return true;
        };
        
        this.callMenu = function(action, args) {
        	var m = document.getElementById('W'+this.menuID);
                var self = this;
        	if (!m || !m.callMenu) {
        		setTimeout(function () {
	        		self.callMenu(action, args);
	        	}, 200);
	        	return;
        	}
        	 
           	args = args || [];
                switch (args.length) {
                    case 5: m.callMenu(action, args[0],args[1],args[2],args[3],args[4]); break; 
                    case 4: m.callMenu(action, args[0],args[1],args[2],args[3]); break; 
                    case 3: m.callMenu(action, args[0],args[1],args[2]); break; 
                    case 2: m.callMenu(action, args[0],args[1]); break; 
                    case 1: m.callMenu(action, args[0]); break; 
                    default:
   	               m.callMenu(action);
		       break;
                }
        };

        this.show = function(service) {
            if (!this.ready) {
                this.onReadyFunction = $LaunchpadUtil.bind(this.show, this);
            } else {
                if (!this.visible || service) {
                	
                    if (!this.menuParent) this.create();

                    if (this.menuParent) {
                        !this.options.actionElement && this.Button && (this.Button.style.backgroundPosition = "0px -72px");
                        !this.options.targetElement && this.setLocation();
                        
                        this.options.targetElement && (this.menuParent.style.visibility = "visible");
                        if (this.menuParent.style && this.menuParent.style.height) {
                            this.menuParent.style.height = "auto";
                        }
                        this.menuParent.style.marginTop = 0;
                        this.menuParent.style.zIndex = 1000;

                        this.callMenu('show', [service]);

                        $LaunchpadUtil.appear(this.menuParent,  this.options.targetElement ? 1 : 0);                
                    }

                    this.visible = true;
                }
            }
            return true;
        };
        
        this.create = function () {
        	
            if (!this.created) {
                this.created = true;
                this.url = "";

                if (this.options.newWindow) {
                    // @todo when opening a new window, really open a widget.bs page or something
                    this.launchpadwindowname = this.launchpadwindowname || "window" + $LaunchpadUtil.random();
                    this.url = this.url || $LaunchpadObject.getURL(this.options.wid, this.options);
                    var newwindow = window.open(this.url, this.launchpadwindowname);
                    newwindow && newwindow.focus && newwindow.focus();

                    return true;
                }

                if (this.options.inline) {
                    this.options.shadow = 0;
                    this.url = $LaunchpadObject.getURL(this.options.wid, this.options);
                    this.menuParent = document.getElementById("Parent" + this.menuID);
                    this.menuParent.innerHTML = $LaunchpadUtil.getTag(this.menuID, this.url, {width: this.options.menuWidth, height: this.options.menuHeight});
                    this.menu = document.getElementById(this.menuID);
                    
                    $LaunchpadUtil.onDomReady($LaunchpadUtil.bind(this.onDomReady, this));
                    
                    return true;
                }
                
                if (this.options.targetElement) {
                    this.options.shadow = 0;
                    this.url = $LaunchpadObject.getURL(this.options.wid, this.options);
                    this.menuParent = $LaunchpadUtil.create('div', { style : "position : relative; width: " + this.options.menuWidth + "px;"  });
                    this.menuParent.style.display = "none";
                    this.menuParent.innerHTML = $LaunchpadUtil.getTag(this.menuID, this.url, {width: this.options.menuWidth, height: this.options.menuHeight});
                    this.menu = this.menuParent.firstChild;
                    
                    $LaunchpadUtil.onDomReady($LaunchpadUtil.bind(this.onDomReady, this));
                    
                    return true;
                } 
               
                this.url = $LaunchpadObject.getURL(this.options.wid, this.options);
                this.menuParent = $LaunchpadUtil.create('div', { 
                	style : "position: absolute; top:0; left: 0; z-index: 1000;" +
                        (this.options.shadow  && false? 'background:transparent url(http://cdn.clearspring.com/launchpad/3947/img/bg-shadow.png) no-repeat scroll 0pt;padding:5px 11px 11px 6px;' : '')
                });


                this.menuParent.style.visibility = "hidden";
                this.menuParent.innerHTML = $LaunchpadUtil.getTag(this.menuID, this.url, {
                	width: this.options.menuWidth, height: this.options.menuHeight});

                this.menu = this.menuParent.firstChild;
                $LaunchpadUtil.onDomReady($LaunchpadUtil.bind(this.onDomReady, this));
            }

            return true;
        };

        this.updateSource = function () {};
        this.getSource = function(source) {
            var blob = $LaunchpadObject.getBlob(source);
            blob = blob.replace(/\n/g, '').replace(/\&amp;/g, '&').replace(/%0A/g, '').replace(/^\s+/, '').replace(/\s+$/, '');        
            return blob;
        };


        //EVENTS
        this.onDomReady = function() {

            if (this.options.targetElement) {
                this.options.targetElement = document.getElementById(this.options.targetElement) || this.options.targetElement;
                this.options.targetElement.innerHTML = "";
                this.options.targetElement.appendChild(this.menuParent);
            } else {
                !this.options.inline && document.body.appendChild(this.menuParent);
            }
        };

        ///////// PRIVATE MEMBERS /////////
        this.setLocation = function () {
        	
            if (this.options.actionElement && !this.Button) {
                this.Button = document.getElementById(this.options.actionElement) || this.options.actionElement;
            }
         
            if (!this.options.targetElement && this.Button) {
                var windowSize = $LaunchpadUtil.windowSize();
                var buttonCoordinates = $LaunchpadUtil.getPosition(this.Button);
                
                buttonCoordinates.width = this.Button.offsetWidth;
                buttonCoordinates.height = this.Button.offsetHeight;

                var LEFTOFFSET = 0;
                var TOPOFFSET = 1;
                var left = (buttonCoordinates.left + this.options.menuWidth) < windowSize.width ? 
                    buttonCoordinates.left + LEFTOFFSET: 
                    buttonCoordinates.left + buttonCoordinates.width - this.options.menuWidth + LEFTOFFSET;
                var top = buttonCoordinates.top + buttonCoordinates.height + TOPOFFSET;

                //make sure not negative cordinates
                top = top > 0 ? top :  buttonCoordinates.top + buttonCoordinates.height + TOPOFFSET;
                left = left > 0 ? left : 0;
                
                window.ActiveXObject && !window.XMLHttpRequest && (top = top - 12);
                
                this.menuParent.style.left = left + "px";
                this.menuParent.style.top = top + "px";
            } 
        };

        this.init(options);
    }
}
/* vim: set expandtab tabstop=4 shiftwidth=4: */

/**
 * Launchpad utility functions.
 *
 * @author dylan
 * @author rajat
 * @author mjk
 * @author tim
 *
 * @version $Id$
 */

if (typeof $LaunchpadUtil == "undefined") {
	
    var $LaunchpadUtil = {
        getTag : function (id, url, options) {
            var ie = navigator.userAgent.toString().indexOf('MSIE')>=0;

            options = options || {};
            options.wmode = options.wmode || 'transparent';
            options.scalemode = options.scalemode || 'noScale';
            options.width = options.width || '100%';
            options.height = options.height || '100%';
            var rv = '<object id="W'+id+'"' + (options.style ? ' style="'+options.style+'"' : '') + ' width="'+options.width+'" height="'+options.height+'" quality="best" '+(ie?'':' data="'+url+'" ')+
                     'pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash">' +
                     '<param name="scalemode" value="'+options.scalemode+'"/>' +
                     '<param name="menu" value="false"/><param name="wmode" value="'+options.wmode+'"/><param name="allowNetworking" value="all"/><param name="allowScriptAccess" value="always"/>'+
                     (ie?'<param name="movie" value="'+url+'" />':'')+' </object>';
            return rv;
        },

        bind : function (fn, scope, args) {
            return function(event) {
                var params;
                event && event.type && (params = [ event ]) || args && (params = args) || (params = []);
                
                window.event && params.push(window.event);
                params.push(event);

                return fn.apply(scope, params);
            };
        },

        elementFromEvent : function (evt) {
            var el = evt.target || evt.srcElement;
	        if (el.nodeType == 3){ el = el.parentNode; }
            return el;
        },


        addEvent : function(el, type, fn) {
	        if (el.addEventListener){ el.addEventListener(type, fn, false); }
	        else {el.attachEvent('on' + type, fn);}
	        return el;
        },

        random : function(min, max) {
            min = min || 1;
            max = max || 1000000;
            return Math.floor(Math.random() * (max - min + 1) + min);
        },

        create : function(tagName, props) {
            var el = document.createElement(tagName);

            for (prop in props) {
	            var val = props[prop];
	            if (typeof val != "function") {
	                switch(prop) {
		                case 'style': el.style.cssText = val; break;
		                default: this.setProperty(el, prop, val); break;
	                }
                }
            }

            return el;
        },

        setProperty : function(el, property, value) {
            var Properties =  {
            'class': 'className', 'for': 'htmlFor', 'colspan': 'colSpan', 'rowspan': 'rowSpan',
            'accesskey': 'accessKey', 'tabindex': 'tabIndex', 'maxlength': 'maxLength',
            'readonly': 'readOnly', 'frameborder': 'frameBorder', 'value': 'value',
            'disabled': 'disabled', 'checked': 'checked', 'multiple': 'multiple', 'selected': 'selected'
            };

            var index = Properties[property];
            if (index){el[index] = value;}
            else {el.setAttribute(property, value);}
            return this;
        },

        appear: function(el, opacity) {
            el.style.display = "block"; 
            el.style.visibility = "visible"; 
	        return;
        },

        getPosition: function(el) {
	        var left = 0, top = 0;
	        do {
		        left += el.offsetLeft || 0;
		        top += el.offsetTop || 0;
		        el = el.offsetParent;
		        
	        } while (el && el.tagName != "BODY");

            if (el && el.tagName == "BODY") {
	            left += el.offsetLeft || 0;
	            top += el.offsetTop || 0;
	        }
	        return {left: left, top: top};
        },

        windowSize : function() {
            var ws;
            //Opera
            (window.opera) && ( ws = { width : document.body.clientWidth, height : document.body.clientHeight });
            //Safari 2
            (document.childNodes && !document.all && !navigator.taintEnabled && !window.xpath) && (ws = { width : window.innerWidth, height : window.innerHeight });

            //IE, Firefox, Safari 3, hack for XHTML vs HTML
            var documentHeight = (document.documentElement.clientHeight && document.documentElement.clientHeight < document.body.clientHeight) ? document.documentElement.clientHeight :  document.body.clientHeight; 
            var documentWidth = (document.documentElement.clientWidth && document.documentElement.clientWidth < document.body.clientWidth) ? document.documentElement.clientWidth :  document.body.clientWidth;	            
            
            return ws || { width : documentWidth - (window.pageXOffset || 0), height : documentHeight - (window.pageYOffset || 0) };
        },

        setOptions : function(orig, newOptions) {
            orig = orig || {};
            newOptions = newOptions || {};
            for (var property in newOptions) {
                orig[property] = newOptions[property];
            }
            return orig;
        },

		// @todo add mappers of settings to TLAs -- maybe belongs at a higher level
        toQueryString : function(source) {
        	
            var queryString = [];
            for (property in source) {
                if (source[property] !== undefined && typeof source[property] != "function" ) {
                    if (source[property].tagName) {
                        var id = source[property].id;
                        if (!id) {
                            id = "id" + this.random();
                            source[property].id = id;
                        }
                        queryString.push(encodeURIComponent(property) + '=' + encodeURIComponent(id));                    
                    } else {
                        if (typeof source[property] == "object") {
                            queryString.push(encodeURIComponent(property) + '=' + encodeURIComponent(this.toQueryString(source[property])));
                        } else {
                            queryString.push(encodeURIComponent(property) + '=' + encodeURIComponent(source[property]));                    
                        }
                    }
                }
            }
            return queryString.join('&');
        },
        
        stopEvent : function(event) {
            event = event || window.event;
            if (event.preventDefault) {
                event.preventDefault();
                event.stopPropagation();
            } else {
                event.returnValue = false;
                event.cancelBubble = true;
            }
        },
        
        onDomReady : function(callback) {
            //check IE's proprietary DOM members
            if(!document.uniqueID && document.expando || window.onDocumentReady) {
                callback();
    	    } else {
    	    
                var tempNode = document.createElement('document:ready');  
                try {
	                tempNode.doScroll && tempNode.doScroll('left');
	                tempNode = null;

                    var csDOM = document.getElementById("clearspringDOM");
                    csDOM && document.body.appendChild(csDOM);
	                window.onDocumentReady = true;
	                callback();
            		
                } catch (err) {}
                
                !window.onDocumentReady && setTimeout(function() { $LaunchpadUtil.onDomReady(callback); }, 20);
            }
        
        }    
    };
}

// Launchpad Menu Analytics - used to track usage across all Launchpad installations
(
function() {
    var analyticsWid = "475db72337b302d4";
    var analyticsUrl = "http://widgets.clearspring.com/o/475db72337b302d4/-/-/-/";

    if (analyticsWid)  {
        document.write($LaunchpadUtil.getTag('W'+analyticsWid, analyticsUrl, {
        	 style: "position:fixed; top:1px; height:1px; width:1px; left:10px; z-index: 2000;", 
             width: 1, height: 1, wmode: 'transparent'}));
    }
}
)();

