/* cache=true */


// Flash Player Version Detection - Rev 1.6
// Detect Client Browser type
// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved.


YAHOO.namespace("gaia.app.FlashUtil");

(function(){
    YAHOO.gaia.app.FlashUtil = function(){
        var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
        var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
        var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
        

        var FU = {
            isIE:isIE,
            isWin:isWin,
            isOpera:isOpera,
            
            ControlVersion: function(){
                var version;
                var axo;
                var e;
                // NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry
                try {
                    // version will be set for 7.X or greater players
                    axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
                    version = axo.GetVariable("$version");
                } 
                catch (e) {
                }
                if (!version)
                    {
                        try {
                            // version will be set for 6.X players only
                            axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
                            // installed player is some revision of 6.0
                            // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
                            // so we have to be careful. 
                            // default to the first public version
                            version = "WIN 6,0,21,0";
                            // throws if AllowScripAccess does not exist (introduced in 6.0r47)		
                            axo.AllowScriptAccess = "always";
                            // safe to call for 6.0r47 or greater
                            version = axo.GetVariable("$version");
                        } 
                        catch (e) {
                        }
                    }
            
                if (!version)
                    {
                        try {
                            // version will be set for 4.X or 5.X player
                            axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
                            version = axo.GetVariable("$version");
                        } 
                        catch (e) {
                        }
                    }

                if (!version)
                    {
                        try {
                            // version will be set for 3.X player
                            axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
                            version = "WIN 3,0,18,0";
                        } 
                        catch (e) {
                        }
                    }

                if (!version)
                    {
                        try {
                            // version will be set for 2.X player
                            axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
                            version = "WIN 2,0,0,11";
                        } 
                        catch (e) {
                            version = -1;
                        }
                    }
	
                return version;
            },

            // JavaScript helper required to detect Flash Player PlugIn version information
            GetSwfVer:function() {
                // NS/Opera version >= 3 check for Flash plugin in plugin array
                var flashVer = -1;
	
                if (navigator.plugins != null && navigator.plugins.length > 0) {
                    if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
                        var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
                        var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
                        var descArray = flashDescription.split(" ");
                        var tempArrayMajor = descArray[2].split(".");			
                        var versionMajor = tempArrayMajor[0];
                        var versionMinor = tempArrayMajor[1];
                        var versionRevision = descArray[3];
                        if (versionRevision == "") {
                            versionRevision = descArray[4];
                        }
                        if (versionRevision[0] == "d") {
                            versionRevision = versionRevision.substring(1);
                        } else if (versionRevision[0] == "r") {
                            versionRevision = versionRevision.substring(1);
                            if (versionRevision.indexOf("d") > 0) {
                                versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
                            }
                        }
                        var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
                    }
                }
                // MSN/WebTV 2.6 supports Flash 4
                else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
                // WebTV 2.5 supports Flash 3
                else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
                // older WebTV supports Flash 2
                else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
                else if ( isIE && isWin && !isOpera ) {
                    flashVer = FU.ControlVersion();
                }	
                return flashVer;
            },

            // When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
            DetectFlashVer: function(reqMajorVer, reqMinorVer, reqRevision){
                versionStr = FU.GetSwfVer();
                if (versionStr == -1 ) {
                    return false;
                } else if (versionStr != 0) {
                    if(isIE && isWin && !isOpera) {
                        // Given "WIN 2,0,0,11"
                        tempArray         = versionStr.split(" "); 	// ["WIN", "2,0,0,11"]
                        tempString        = tempArray[1];			// "2,0,0,11"
                        versionArray      = tempString.split(",");	// ['2', '0', '0', '11']
                    } else {
                        versionArray      = versionStr.split(".");
                    }
                    var versionMajor      = versionArray[0];
                    var versionMinor      = versionArray[1];
                    var versionRevision   = versionArray[2];

                    // is the major.revision >= requested major.revision AND the minor version >= requested minor
                    if (versionMajor > parseFloat(reqMajorVer)) {
                        return true;
                    } else if (versionMajor == parseFloat(reqMajorVer)) {
                        if (versionMinor > parseFloat(reqMinorVer))
                            return true;
                        else if (versionMinor == parseFloat(reqMinorVer)) {
                            if (versionRevision >= parseFloat(reqRevision))
                                return true;
                        }
                    }
                    return false;
                }
            },

            AC_AddExtension: function(src, ext)
            {
                if (src.indexOf('?') != -1)
                    return src.replace(/\?/, ext+'?'); 
                else
                    return src + ext;
            },

            AC_Generateobj: function(objAttrs, params, embedAttrs,div_id) { 
                var str = '';
                if (isIE && isWin && !isOpera)
                    {
                        str += '<object ';
                        for (var i in objAttrs)
                            str += i + '="' + objAttrs[i] + '" ';
                        str += '>';
                        for (var i in params)
                            str += '<param name="' + i + '" value="' + params[i] + '" /> ';
                        str += '</object>';
                    } else {
                    str += '<embed ';
                    for (var i in embedAttrs)
                        str += i + '="' + embedAttrs[i] + '" ';
                    str += '> </embed>';
                }

                var el = document.getElementById(div_id);
                if(!el) {
                    el = document.createElement("div");
                    document.body.appendChild(el);
                    el.setAttribute('id',div_id);
                }

                var flObj = null;
                if (isIE && isWin && !isOpera)
                    {
                        flObj = document.createElement("object");
                        for (var i in objAttrs)
                            flObj.setAttribute(i,objAttrs[i]);
                        for (var i in params){
                            var param = document.createElement("param");
                            param.setAttribute("name",i);
                            param.setAttribute("value",params[i]);
                            flObj.appendChild(param);
                        }
                    } else {
                    flObj = document.createElement("embed");
                    for (var i in embedAttrs)
                        flObj.setAttribute(i,embedAttrs[i]);
  	   
                }

                el.appendChild(flObj);
    
            },

            AC_FL_RunContent: function(){
                var ret = 
                FU.AC_GetArgs
                (  arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
                   , "application/x-shockwave-flash"
                   );
                FU.AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs,ret.div_id);
            },
            AC_GetArgs: function(args, ext, srcParamName, classid, mimeType){
                var ret = new Object();
                ret.embedAttrs = new Object();
                ret.params = new Object();
                ret.objAttrs = new Object();
                ret.div_id = '_flashMovie';
                for (var i=0; i < args.length; i=i+2){
                    var currArg = args[i].toLowerCase();    

                    switch (currArg){	
                    case "div_id":
                        ret.div_id = args[i+1];
                        break;
                    case "classid":
                        break;
                    case "pluginspage":
                        ret.embedAttrs[args[i]] = args[i+1];
                        break;
                    case "src":
                    case "movie":	
                        args[i+1] = FU.AC_AddExtension(args[i+1], ext);
                        ret.embedAttrs["src"] = args[i+1];
                        ret.params[srcParamName] = args[i+1];
                        break;
                    case "onafterupdate":
                    case "onbeforeupdate":
                    case "onblur":
                    case "oncellchange":
                    case "onclick":
                    case "ondblClick":
                    case "ondrag":
                    case "ondragend":
                    case "ondragenter":
                    case "ondragleave":
                    case "ondragover":
                    case "ondrop":
                    case "onfinish":
                    case "onfocus":
                    case "onhelp":
                    case "onmousedown":
                    case "onmouseup":
                    case "onmouseover":
                    case "onmousemove":
                    case "onmouseout":
                    case "onkeypress":
                    case "onkeydown":
                    case "onkeyup":
                    case "onload":
                    case "onlosecapture":
                    case "onpropertychange":
                    case "onreadystatechange":
                    case "onrowsdelete":
                    case "onrowenter":
                    case "onrowexit":
                    case "onrowsinserted":
                    case "onstart":
                    case "onscroll":
                    case "onbeforeeditfocus":
                    case "onactivate":
                    case "onbeforedeactivate":
                    case "ondeactivate":
                    case "type":
                    case "codebase":
                        ret.objAttrs[args[i]] = args[i+1];
                        break;
                    case "id":
                    case "width":
                    case "height":
                    case "align":
                    case "vspace": 
                    case "hspace":
                    case "class":
                    case "title":
                    case "accesskey":
                    case "name":
                    case "tabindex":
                        ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
                        break;
                    default:
                        ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
                    }
                }
                ret.objAttrs["classid"] = classid;
                if (mimeType) ret.embedAttrs["type"] = mimeType;
                return ret;
            }
        };
        return FU;

    }
})();

//
// Copyright (c) 2008 Paul Duncan (paul@pablotron.org)
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

/**
 * Persist - top-level namespace for Persist library.
 */
YAHOO.namespace("gaia.app.Persist");
YAHOO.gaia.app.Persist = (function() {
        var VERSION = '0.1.0', P, B, esc, init, empty, ec;
        ec = YAHOO.util.Cookie;
        // empty function
        empty = function() { };
        // escape spaces in name
        esc = function(str) {
            return 'PS' + str.replace(/_/g, '__').replace(/ /g, '_s');
        };

        C = {
            /* 
             * Backend search order.
             * 
             * Note that the search order is significant; the backends are
             * listed in order of capacity, and many browsers
             * support multiple backends, so changing the search order could
             * result in a browser choosing a less capable backend.
             * 
             */ 
            search_order: [
                           // TODO: air
                           'flash',
                           'gears',
                           'localstorage',
                           'whatwg_db', 
                           'globalstorage',
                           'ie', 
                           'cookie'
                           ],

            // valid name regular expression
            name_re: /^[a-z][a-z0-9_ -]+$/i,

            // list of backend methods
            methods: [
                      'init',
                      'setStatus',//used for flash only
                      'get', 
                      'set', 
                      'remove', 
                      'load', 
                      'save'
                      // TODO: clear method?
                      ],

            // sql for db backends (gears and db)
            sql: {
                version:  '1', // db schema version

                create:   "CREATE TABLE IF NOT EXISTS persist_data (k TEXT UNIQUE NOT NULL PRIMARY KEY, v TEXT NOT NULL)",
                get:      "SELECT v FROM persist_data WHERE k = ?",
                set:      "INSERT INTO persist_data(k, v) VALUES (?, ?)",
                remove:   "DELETE FROM persist_data WHERE k = ?" 
            },

            // default flash configuration
            flash: {
                // ID of wrapper element
                div_id:   '_persist_flash_wrap',

                // id of flash object/embed
                id:       'persistFlash',

                allowscriptaccess: 'sameDomain',
                util: new YAHOO.gaia.app.FlashUtil(),
                requiredMajorVersion: 9,
                requiredMinorVersion: 8,
                requiredRevision: 28,
                // default path to flash object
                path: '/src/js/persist/persist',
                size: { w:1, h:1 },

                // arguments passed to flash object
                args: {
                    autostart: true
                }
            } 
        };

        // built-in backends
        B = {
            // gears db backend (webkit, Safari 3.1+)
            // (src: http://code.google.com/apis/gears/api_database.html)
            gears: {
                // no known limit
                size:   -1,

                test: function() {
                    // test for gears
                    return (window.google && window.google.gears) ? true : false;
                },

                methods: {
                    transaction: function(fn) {
                        var db = this.db;

                        // begin transaction
                        db.execute('BEGIN').close();

                        // call callback fn
                        fn.call(this, db);

                        // commit changes
                        db.execute('COMMIT').close();
                    },

                    setStatus: function(){return},

                    init: function() {
                        var db;

                        // create database handle (TODO: add schema version?)
                        db = this.db = google.gears.factory.create('beta.database');

                        // open database
                        // from gears ref:
                        //
                        // Currently the name, if supplied and of length greater than
                        // zero, must consist only of visible ASCII characters
                        // excluding the following characters:
                        //
                        //   / \ : * ? " < > | ; ,
                        db.open(esc(this.name));

                        // create table
                        db.execute(C.sql.create).close();
                    },

                    get: function(key, fn, scope) {
                        var r, sql = C.sql.get;

                        // if callback isn't defined, then return
                        if (!fn)
                            return;

                        // begin transaction
                        this.transaction(function (t) {
                                             // exec query
                                             r = t.execute(sql, [key]);

                                             // call callback
                                             if (r.isValidRow())
                                                 fn.call(scope || this, true, r.field(0));
                                             else
                                                 fn.call(scope || this, false, null);

                                             // close result set
                                             r.close();
                                         });
                    },

                    set: function(key, val, fn, scope) {
                        var rm_sql = C.sql.remove,
                        sql    = C.sql.set, r;

                        // begin set transaction
                        this.transaction(function(t) {
                                             // exec remove query
                                             t.execute(rm_sql, [key]).close();

                                             // exec set query
                                             t.execute(sql, [key, val]).close();
            
                                             // run callback
                                             if (fn)
                                                 fn.call(scope || this, true, val);
                                         });
                    },

                    // begin remove transaction
                    remove: function(key, fn, scope) {
                        var get_sql = C.sql.get;
                        sql = C.sql.remove,
                        r, val;

                        this.transaction(function(t) {
                                             // if a callback was defined, then get the old
                                             // value before removing it
                                             if (fn) {
                                                 // exec get query
                                                 r = t.execute(get_sql, [key]);

                                                 if (r.isValidRow()) {
                                                     // key exists, get value 
                                                     val = r.field(0);

                                                     // exec remove query
                                                     t.execute(sql, [key]).close();

                                                     // exec callback
                                                     fn.call(scope || this, true, val);
                                                 } else {
                                                     // key does not exist, exec callback
                                                     fn.call(scope || this, false, null);
                                                 }

                                                 // close result set
                                                 r.close();
                                             } else {
                                                 // no callback was defined, so just remove the
                                                 // data without checking the old value

                                                 // exec remove query
                                                 t.execute(sql, [key]).close();
                                             }
                                         });
                    } 
                }
            }, 

            // whatwg db backend (webkit, Safari 3.1+)
            // (src: whatwg and http://webkit.org/misc/DatabaseExample.html)
            whatwg_db: {
                size:   200 * 1024,
                test: function() {
                    var name = 'PersistJS Test', 
                    desc = 'Persistent database test.';

                    // test for openDatabase
                    if (!window.openDatabase)
                        return false;

                    // make sure openDatabase works
                    // XXX: will this leak a db handle and/or waste space?
                    if (!window.openDatabase(name, C.sql.version, desc, B.whatwg_db.size))
                        return false;

                    return true;
                },

                methods: {
                    transaction: function(fn) {
                        if (!this.db_created) {
                            var sql = C.sql.create;

                            this.db.transaction(function(t) {
                                                    // create table
                                                    t.executeSql(sql, [], function() {
                                                                     this.db_created = true;
                                                                 });
                                                }, empty); // trap exception
                        } 

                        this.db.transaction(fn);
                    },

                    setStatus: function(){return},
                    init:
                    function() {
                        var desc, size; 
          
                        // init description and size
                        desc = this.o.about || "Persistent storage for " + this.name;
                        size = this.o.size || B.whatwg_db.size;

                        // create database handle
                        this.db = openDatabase(this.name, C.sql.version, desc, size);
                    },

                    get: function(key, fn, scope) {
                        var sql = C.sql.get;

                        // if callback isn't defined, then return
                        if (!fn)
                            return;

                        // get callback scope
                        scope = scope || this;

                        // begin transaction
                        this.transaction(function (t) {
                                             t.executeSql(sql, [key], function(t, r) {
                                                              if (r.rows.length > 0)
                                                                  fn.call(scope, true, r.rows.item(0)['v']);
                                                              else
                                                                  fn.call(scope, false, null);
                                                          });
                                         });
                    },

                    set: function(key, val, fn, scope) {
                        var rm_sql = C.sql.remove,
                        sql    = C.sql.set;

                        // begin set transaction
                        this.transaction(function(t) {
                                             // exec remove query
                                             t.executeSql(rm_sql, [key], function() {
                                                              // exec set query
                                                              t.executeSql(sql, [key, val], function(t, r) {
                                                                               // run callback
                                                                               if (fn)
                                                                                   fn.call(scope || this, true, val);
                                                                           });
                                                          });
                                         });

                        return val;
                    },

                    // begin remove transaction
                    remove: function(key, fn, scope) {
                        var get_sql = C.sql.get;
                        sql = C.sql.remove;

                        this.transaction(function(t) {
                                             // if a callback was defined, then get the old
                                             // value before removing it
                                             if (fn) {
                                                 // exec get query
                                                 t.executeSql(get_sql, [key], function(t, r) {
                                                                  if (r.rows.length > 0) {
                                                                      // key exists, get value 
                                                                      var val = r.rows.item(0)['v'];

                                                                      // exec remove query
                                                                      t.executeSql(sql, [key], function(t, r) {
                                                                                       // exec callback
                                                                                       fn.call(scope || this, true, val);
                                                                                   });
                                                                  } else {
                                                                      // key does not exist, exec callback
                                                                      fn.call(scope || this, false, null);
                                                                  }
                                                              });
                                             } else {
                                                 // no callback was defined, so just remove the
                                                 // data without checking the old value

                                                 // exec remove query
                                                 t.executeSql(sql, [key]);
                                             }
                                         });
                    } 
                }
            }, 
    
            // globalstorage backend (globalStorage, FF2+, IE8+)
            // (src: http://developer.mozilla.org/en/docs/DOM:Storage#globalStorage)
            //
            // TODO: test to see if IE8 uses object literal semantics or
            // getItem/setItem/removeItem semantics
            globalstorage: {
                // (5 meg limit, src: http://ejohn.org/blog/dom-storage-answers/)
                size: 5 * 1024 * 1024,

                test: function() {
                    return window.globalStorage ? true : false;
                },

                methods: {
                    key: function(key) {
                        return esc(this.name) + esc(key);
                    },
                    
                    setStatus: function(){return},
                    init: function() {
                        this.store = globalStorage[this.o.domain];
                    },

                    get: function(key, fn, scope) {
                        // expand key
                        key = this.key(key);

                        if (fn)
                            fn.call(scope || this, true, this.store.getItem(key));
                    },

                    set: function(key, val, fn, scope) {
                        // expand key
                        key = this.key(key);

                        // set value
                        this.store.setItem(key, val);

                        if (fn)
                            fn.call(scope || this, true, val);
                    },

                    remove: function(key, fn, scope) {
                        var val;

                        // expand key
                        key = this.key(key);

                        // get value
                        val = this.store[key];

                        // delete value
                        this.store.removeItem(key);

                        if (fn)
                            fn.call(scope || this, (val !== null), val);
                    } 
                }
            }, 
    
            // localstorage backend (globalStorage, FF2+, IE8+)
            // (src: http://www.whatwg.org/specs/web-apps/current-work/#the-localstorage)
            localstorage: {
                // (unknown?)
                size: -1,

                test: function() {
                    return window.localStorage ? true : false;
                },

                methods: {
                    key: function(key) {
                        return esc(this.name) + esc(key);
                    },
                    
                    
                    setStatus: function(){return},
                    init: function() {
                        this.store = localStorage;
                    },

                    get: function(key, fn, scope) {
                        // expand key
                        key = this.key(key);

                        if (fn)
                            fn.call(scope || this, true, this.store.getItem(key));
                    },

                    set: function(key, val, fn, scope) {
                        // expand key
                        key = this.key(key);

                        // set value
                        this.store.setItem(key, val);

                        if (fn)
                            fn.call(scope || this, true, val);
                    },

                    remove: function(key, fn, scope) {
                        var val;

                        // expand key
                        key = this.key(key);

                        // get value
                        val = this.getItem(key);

                        // delete value
                        this.store.removeItem(key);

                        if (fn)
                            fn.call(scope || this, (val !== null), val);
                    } 
                }
            }, 
    
            // IE backend
            ie: {
                prefix:   '_persist_data-',
                // style:    'display:none; behavior:url(#default#userdata);',

                // 64k limit
                size:     64 * 1024,

                test: function() {
                    // make sure we're dealing with IE
                    // (src: http://javariet.dk/shared/browser_dom.htm)
                    return window.ActiveXObject ? true : false;
                },

                make_userdata: function(id) {
                    var el = document.createElement('div');

                    // set element properties
                    el.id = id;
                    el.style.display = 'none';
                    el.addBehavior('#default#userData');

                    // append element to body
                    document.body.appendChild(el);

                    // return element
                    return el;
                },

                methods: {
                    init: function() {
                        var id = B.ie.prefix + esc(this.name);

                        // save element
                        this.el = B.ie.make_userdata(id);

                        // load data
                        if (this.o.defer)
                            this.load();
                    },
                    
                    setStatus: function(){return},
                    get: function(key, fn, scope) {
                        var val;

                        // expand key
                        key = esc(key);

                        // load data
                        if (!this.o.defer)
                            this.load();

                        // get value
                        val = this.el.getAttribute(key);

                        // call fn
                        if (fn)
                            fn.call(scope || this, val ? true : false, val);
                    },

                    set: function(key, val, fn, scope) {
                        // expand key
                        key = esc(key);
          
                        // set attribute
                        this.el.setAttribute(key, val);

                        // save data
                        if (!this.o.defer)
                            this.save();

                        // call fn
                        if (fn)
                            fn.call(scope || this, true, val);
                    },

                    load: function() {
                        this.el.load(esc(this.name));
                    },

                    save: function() {
                        this.el.save(esc(this.name));
                    }
                }
            },

            // cookie backend
            // uses easycookie: http://pablotron.org/software/easy_cookie/
            cookie: {
                delim: ':',

                // 4k limit (low-ball this limit to handle browser weirdness, and 
                // so we don't hose session cookies)
                size: 4000,

                test: function() {

                    return true;
                },

                methods: {
                    key: function(key) {
                        return this.name + B.cookie.delim + key;
                    },

                    
                    setStatus: function(){return},

                    get: function(key, fn, scope) {

                        // get value
                        val = ec.getSub(this.name,key);

                        // call fn
                        if (fn)
                            fn.call(scope || this, val != null, val);
                    },

                    set: function(key, val, fn, scope) {

                        // save value
                        ec.setSub(this.name,key, val, this.o);
                        //console.log(this.name+" "+key+" "+val);

                        // call fn
                        if (fn)
                            fn.call(scope || this, true, val);
                    },

                    remove: function(key, val, fn, scope) {
                        var val;


                        // remove cookie
                        val = this.get(this.name,key);
                        ec.removeSub(this.name,key);

                        // call fn
                        if (fn)
                            fn.call(scope || this, val != null, val);
                    } 
                }
            },

            // flash backend (requires flash 8 or newer)
            // http://kb.adobe.com/selfservice/viewContent.do?externalId=tn_16194&sliceId=1
            // http://livedocs.adobe.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002200.html
            flash: {

                test: function() {

                    var MSIE = navigator.userAgent.match(/MSIE [6]/);

                    if(MSIE) return false;
                    var cfg = C.flash;
                    var hasProductInstall = cfg.util.DetectFlashVer(8, 0, 0);
                    if ( hasProductInstall ) {
                        return true;
                    }
                    else {
                        return false;
                    }
                },  
                methods: {
                    movieLoaded:0,
                    tempData:[],
                    init: function() {
                        if (!B.flash.el) {
                            var o, key, el, cfg = C.flash;
                            var F = cfg.util;
                            // Version check for the Flash Player that has the ability to start Player Product Install (6.0r65)
                            var hasProductInstall = F.DetectFlashVer(8, 0, 0);
                            // Version check based upon the values defined in globals
                            var hasRequestedVersion = F.DetectFlashVer(cfg.requiredMajorVersion, cfg.requiredMinorVersion, cfg.requiredRevision);
                            if ( hasProductInstall && !hasRequestedVersion ) {
                                var MMPlayerType = (F.isIE == true) ? "ActiveX" : "PlugIn";
                                var MMredirectURL = window.location;
                                document.title = document.title.slice(0, 47) + " - Flash Player Installation";
                                var MMdoctitle = document.title;
                                F.AC_FL_RunContent(
                                                 "div_id", cfg.div_id,
                                                 "src", this.o.swf_path || cfg.path,
                                                 "FlashVars", "autoplay=true",
                                                 "width", "1",
                                                 "height", "1",
                                                 "align", "middle",
                                                 "id", cfg.id,
                                                 "quality", "high",
                                                 "name", cfg.id,
                                                 "allowScriptAccess","sameDomain",
                                                 "type", "application/x-shockwave-flash",
                                                 "pluginspage", "http://www.adobe.com/go/getflashplayer"
                                                 );
                            } else if (hasRequestedVersion) {
                                // if we've detected an acceptable version
                                // embed the Flash Content SWF when all tests are passed
                                F.AC_FL_RunContent(
                                                 "div_id", cfg.div_id,
                                                 "src", this.o.swf_path || cfg.path,
                                                 "width", "1",
                                                 "height", "1",
                                                 "align", "middle",
                                                 "id", cfg.id,
                                                 "quality", "high",
                                                 "name", cfg.id,
                                                 "allowScriptAccess","sameDomain",
                                                 "type", "application/x-shockwave-flash",
                                                 "pluginspage", "http://www.adobe.com/go/getflashplayer"
                                                 );
                            } else {
                                return;
                            }
                            B.flash.el = document.getElementById(cfg.id);
                        }

                        // use singleton flash element
                        this.el = B.flash.el;
                    },

                    
                    setStatus: function(status){
                       
                        //console.log("hello " +status);
                        if(this.movieLoaded ==0 && status>0) {
                            for(i=0;i<this.tempData.length;i++) {
                                var tData = this.tempData[i];
                                this.el.set(tData.name,tData.key,tData.val);
                            }
                            this.movieLoaded = 1;
                        }
                    },

                    get: function(key, fn, scope) {
                        var val, fl = B.flash;

                        if(!this.movieLoaded) {
                            return null;
                        }
                        // escape key
                        key = esc(key);

                        // get value
                        val = this.el.get(this.name, key);

                        // call handler
                        if (fn)
                            fn.call(scope || this, val !== null, val);
                    },

                    set: function(key, val, fn, scope) {
                        var old_val,fl = B.flash;

                        if(!this.movieLoaded) {
                            //console.log('status for flash is:'+this.movieLoaded);
                            this.tempData.push({name:this.name,key:key,val:val});
                            return null;
                        };

                        // escape key
                        key = esc(key);
                        old_val = this.el.set(this.name, key, val);

                        // call handler
                        if (fn){
                            fn.call(scope || this, true, val);
                        }

                    },

                    remove: function(key, fn, scope) {
                        var val;

                        // get key
                        key = esc(key);

                        // remove old value
                        val = this.el.remove(this.name, key);

                        // call handler
                        if (fn)
                            fn.call(scope || this, true, val);
                    }
                }
            }
        };

        // init function
        var init = function() {
            var i, l, b, key, fns = C.methods, keys = C.search_order;

            // set all functions to the empty function
            for (i = 0, l = fns.length; i < l; i++) 
                P.Store.prototype[fns[i]] = empty;

            // clear type and size
            P.type = null;
            P.size = -1;

            // loop over all backends and test for each one
            for (i = 0, l = keys.length; !P.type && i < l; i++) {
                b = B[keys[i]];

                // test for backend
                if (b.test()) {
                    // found backend, save type and size
                    P.type = keys[i];
                    P.size = b.size;

                    // extend store prototype with backend methods
                    for (key in b.methods){
                        P.Store.prototype[key] = b.methods[key];
                    }
                    break;
                }
            }

            // mark library as initialized
            P._init = true;
        };

        // create top-level namespace
        P = {
            // version of persist library
            VERSION: VERSION,

            // backend type and size limit
            type: null,
            size: 0,

            // expose init function
            // init: init,


            add: function(o) {
                // add to backend hash
                B[o.id] = o;

                // add backend to front of search order
                C.search_order = [o.id].concat(C.search_order);

                // re-initialize library
                init();
            },

            remove: function(id) {
                var ofs = C.search_order.indexOf(id);
                if (ofs < 0)
                    return;

                // remove from search order
                C.search_order.splice(ofs, 1);

                // delete from lut
                delete B[id];

                // re-initialize library
                init();
            },

            // expose easycookie API
            Cookie: ec,

            // store API
            Store: function(name, o) {
                // verify name
                if (!C.name_re.exec(name))
                    throw new Error("Invalid name");

                // XXX: should we lazy-load type?
                // if (!P._init)
                //   init();

                if (!P.type)
                    throw new Error("No suitable storage found");

                o = o || {};
                this.name = name;

                // get domain (XXX: does this localdomain fix work?)
                o.domain = o.domain || location.hostname || 'localhost.localdomain';

                this.o = o;

                // expires in 2 years
                o.expires = o.expires || 365 * 2;

                // set path to root
                o.path = o.path || '/';

                // call init function
                this.init();
            } 
        };

        // init persist
        init();

        // return top-level namespace
        return P;
    })();


YAHOO.namespace("gaia.util");
YAHOO.namespace('gaia.app.Gim');

YAHOO.gaia.util.dump = function (arr,level) {
    var dumped_text = "";
    if (!level) {
        level = 0;
    }
    //The padding given at the beginning of the line.
    var level_padding = "";
    for (var j=0; j<level + 1; j++) {
        level_padding += "    ";
        if (level > 5) {
            level_padding += '...';
            return level_padding;
        }
    }
    // arrays hashes and objects
    if (typeof(arr) == 'object') {
        for (var item in arr) if (YAHOO.lang.hasOwnProperty(arr, item)) {
            var value = arr[item];
            if(typeof(value) == 'object') {
                // recursion occurs here because it is an object / hash / etc
                dumped_text += level_padding + "'" + item + "' ...\n";
                dumped_text += YAHOO.gaia.util.dump(value,level+1);
            }
            else {
                // does not have anything deeper at that point
                dumped_text += level_padding + "'" + item + "' => ("+typeof(value)+") \"" + value + "\"\n";
            }
        }
    }
    else {
        // strings, etc are all output normally
        dumped_text = "("+typeof(arr)+") \"" + arr + "\"";
    }
    return dumped_text;
};


(function(){
YAHOO.gaia.app.Gim.params = {   
    LOGIN_COUNTER:0,
    SCROLL_TIMEOUT:null,
    OLD_HEADER:document.title,
    HEADER_MESSAGE:null,
    P_STORE: null,
    P_STORE_SWF_PATH:"http://" +  GAIA_config("graphics_server") +'/src/js/persist/persist',
    GAPI_URI:"http://" + GAIA_config("main_server") + '/gapi/rest/gim/?',
    GAPI_SECURE_URI:"https://" + GAIA_config("main_server") + '/gapi/rest/gim/?',
    DEBUG: false,
    PS_MSG_VAR: 'gimMsgStorage',
    REQUEST_TIMEOUT:((navigator.userAgent.indexOf("Firefox")>-1 || navigator.userAgent.indexOf("Camino") >-1 || window.opera) && !document.all)?5000:40000,
    DEFAULT_ICON:  "http://" + GAIA_config('graphics_server') + "/images/gim/ic_gim_aimuser_29x23.gif",
    CHAT_ICON: "http://" + GAIA_config('graphics_server') + "/images/gim/rs_gim_bublogo_44x37.png",
    BLANK_ICON: "http://" + GAIA_config('graphics_server') + "/images/1x1.gif",
    USE_EMOTICONS: true,
    GIM_SUFFIX: '@gaiaonline.com',
    GUILD_BOT_NAME: 'gaiaguildbot',
    EMOTICON_URI:  "http://" + GAIA_config('graphics_server') + "/images/common/smilies/",
    temp_count:0,
    gUserId:'',
    seqKey:'',
    seqCookies:null,
    gXid:'',
    settingsCookies:'',
    settings:null,
    forceGimAuth:'',
    gSignature:'',
    timestamp:'',
    listenerURI:'',
    loginAttempts:0,
    pStoreKey:'',
    gSecret:'',
    glauncher:null,
    userId:null,
    debugWindow:null,
    msgWindow:null,
    blopen:'',
    onlineCount:0,
    blWasOpen:false,
    blmessage:'',
    gFriendsList:[],
    friendslist:[],
    pollingInt:5,
    blLoaded:false,
    hasGaiaGroup:false,
    emoticons: [
        {code:[':D',':-D'],description:'Very Happy',path:'icon_biggrin.gif'},
        {code:[':)',':-)'],description:'Smile',path:'icon_smile.gif'},
        {code:[':-[',':-!',':oops:'],description:'Embarassed',path:'icon_redface.gif'},
        {code:[":'(",'T_T'],description:'Crying',path:'icon_crying.gif'},
        {code:[':stare:'],description:'Stare',path:'icon_stare.gif'},
        {code:[':XD'],description:'XD',path:'icon_xd.gif'},
        {code:[':3nod:'],description:':3 Nodding',path:'icon_3nodding.gif'},
        {code:[':big:'],description:'Big Laugh',path:'icon_blaugh.gif'},
        {code:[':gonk:'],description:'Gonk',path:'icon_gonk.gif'},
        {code:['\>:o',':scream:'],description:'Scream',path:'icon_scream.gif'},
        {code:[':vein:'],description:'Stressed',path:'icon_stressed.gif'},
        {code:[':sweat:'],description:'Sweat',path:'icon_sweatdrop.gif'},
        {code:[':heart:','\<3'],description:'Heart',path:'icon_heart.gif'},
        {code:[':xp:'],description:'XP',path:'icon_xp.gif'},
        {code:[':whee:'],description:'Whee!',path:'icon_whee.gif'},
        {code:[';)',';-)',':wink:'],description:'Wink',path:'icon_wink.gif'},
        {code:[':(',':-('],description:'Sad',path:'icon_frown.gif'},
        {code:['=-o',':o'],description:'Surprised',path:'icon_surprised.gif'},
        {code:[':shock:'],description:'Shocked',path:'icon_eek.gif'},
        {code:[':?:'],description:'Question?',path:'icon_question.gif'},
        {code:[':?'],description:'Confused',path:'icon_confused.gif'},
        {code:['8-)','8)'],description:'Cool',path:'icon_cool.gif'},
        {code:[':lol:'],description:'Laughing',path:'icon_lol.gif'},
        {code:[':x'],description:'Mad',path:'icon_mad.gif'},
        {code:[':pirate:'],description:'Pirate',path:'icon_pirate.gif'},
        {code:[':p',':-p'],description:'Razz',path:'icon_razz.gif'},
        {code:[':cry:'],description:'Very sad',path:'icon_cry.gif'},
        {code:[':twisted:',':evil:'],description:'Evil',path:'icon_evil.gif'},
        {code:[":-\\",":-\/",':roll:'],description:'Rolling eyes',path:'icon_rolleyes.gif'},
        {code:[':!:'],description:'Exclamation!',path:'icon_exclaim.gif'},
        {code:[':idea:'],description:'Idea',path:'icon_idea.gif'},
        {code:[':arrow:'],description:'Arrow',path:'icon_arrow.gif'},
        {code:[':|'],description:'Neutral',path:'icon_neutral.gif'},
        {code:[':mrgreen:'],description:'Mr. Green',path:'icon_mrgreen.gif'},
        {code:[':ninja:'],description:'Ninja',path:'icon_ninja.gif'},
        {code:[':-*',':cute:'],description:'Cute laugh',path:'icon_4laugh.gif'},
        {code:[':rofl:'],description:'ROFL',path:'icon_rofl.gif'},
        {code:[':talk2hand:'],description:'Talk to the hand',path:'icon_talk2hand.gif'},
        {code:[':burning:'],description:'AUGH! My eyes!',path:'burning_eyes.gif'},
        {code:[':cheese:'],description:'Cheese and whine',path:'cheese_whine.gif'},
        {code:[':dramallama:'],description:'Drama llama',path:'dramallama.gif'},
        {code:[':wahmbulance:'],description:'Wahhhhhmbulance',path:'icon_wahmbulance.gif'},
        {code:[':emo:'],description:'Emo',path:'emo.gif'}
    ],
    transactions: {
        getSessionData:'method=aimauth&type=header'
    },
    callbacks: {
        setPermitDeny:["YAHOO.gaia.app.Gim.callbacks.setPermitDeny"],
        getPermitDeny:["YAHOO.gaia.app.Gim.callbacks.getPermitDeny"],
        getBuddyInfo: ["YAHOO.gaia.app.Gim.callbacks.getBuddyInfo"],
        getBuddyList: ["YAHOO.gaia.app.Gim.callbacks.getBuddyList"],
        sendTextIM: ["YAHOO.gaia.app.Gim.callbacks.sendTextIM"],
        getPresenceInfo: ["YAHOO.gaia.app.Gim.callbacks.getPresenceInfo"],
        typingStatus:["YAHOO.gaia.app.Gim.callbacks.typingStatus"],
        setState:["YAHOO.gaia.app.Gim.callbacks.setState"],
        endSession:["YAHOO.gaia.app.Gim.callbacks.endSession"],
        addGroup:["YAHOO.gaia.app.Gim.callbacks.addGroup"],
        getSessionData:["YAHOO.gaia.app.Gim.callbacks.getSessionData"],
        listener: {
            im: ["YAHOO.gaia.app.Gim.ui.acceptIncomingMessage"],
            offlineIM:["YAHOO.gaia.app.Gim.ui.acceptIncomingMessage"],
            imData:["YAHOO.gaia.app.Gim.callbacks.acceptDataIM"],
            buddylist:["YAHOO.gaia.app.Gim.ui.createBuddyList"],
            presence:["YAHOO.gaia.app.Gim.ui.updateBuddyList"],
            typing:["YAHOO.gaia.app.Gim.ui.updateTypingStatus"],
            sessionEnded:["YAHOO.gaia.app.Gim.callbacks.sessionEnded"]
        }
    }
}

})();

(function() {
 
    var U = YAHOO.gaia.util;
    var params = YAHOO.gaia.app.Gim.params;
    var E = YAHOO.util.Event;
    var D = YAHOO.util.Dom;
    var C = YAHOO.util.Cookie;

    YAHOO.gaia.app.Gim.widgets = {

        header:{
            launch: function(settings){
                params.settings = settings;
                params.gUserId = settings.gUserId;
                params.settingsCookies = params.gUserId + '_settingsCookies';
                params.forceGimAuth = params.gUserId + '_forceGimAuth';
                params.glauncher = new YAHOO.gaia.app.Gim.GlobalLauncher(); 
                params.glauncher.init({gUserId: params.gUserId});
                params.listenerURI = settings.listenerURI + "&f=json&c=YAHOO%2Egaia%2Eapp%2EGim%2Ecore%2Elisten&timeout=" + params.REQUEST_TIMEOUT;
                params.seqKey = settings.seqKey;
                params.seqCookies = C.getSubs(params.seqKey);
                params.blopen = params.gUserId + "_" + "blopen";
                params.blmessage = params.gUserId + "_" + "blmessage";
                params.autoLogin = settings.autoLogin;
                if(!params.seqCookies){
                    params.seqCookies ={lastTime:0,lastNum:0,mCount:0,lastViewTime:0};
                }
                var now = new Date();
                now.setHours(now.getHours()+24);
                
                C.setSub(params.settingsCookies,"enablePopup",params.settings.enablePopup,{domain:document.domain,path:'/',expires:now});
                if(params.autoLogin == 1){
                    YAHOO.gaia.app.Gim.core.destroyListenerObject(true);
                }
                
                YAHOO.gaia.app.Gim.core.startTimers();
                
                //if Zomg is now logged off of GIM, wait 3 minutes and then reauth in GIM.
                //This assures the person is not merely clicking through pages.
                var force_auth = C.getSub(params.forceGimAuth, 'forceGimAuth');
                if(settings.force_gim_auth == 1 || (typeof(force_auth) != 'undefined' && force_auth == 1) ){
                    C.setSub(params.forceGimAuth,"forceGimAuth",'1',{domain:document.domain,path:'/'});
                    window.setTimeout("YAHOO.gaia.app.Gim.transactions.getSessionData(true)", 180000);

                }
                //YAHOO.gaia.app.Gim.transactions.getGaiaBuddyList();
            }
        }

    }

    /**
     *	YAHOO.gaia.app.Gim.core contains all of the methods that are REQUIRED for the API to funtion.
     */
    YAHOO.gaia.app.Gim.core = {
        AIMData:[],
        authAttempts:0,
        requestInterval:null,
        subscriptions: null,
        activeSession: false,
        pendingTransaction: null,
        msgQueue:[],
        /**
         *	Checks to see if the browser the user is in is part of the "officially supported browser matrix"
         */
        supportedBrowser: function() {
            if(window.opera || document.layers || !document.getElementById) return false;
            var FF = navigator.userAgent.match("Firefox/[1-3]\.");
            var MSIE = navigator.userAgent.match(/MSIE [6-9]/);
            var SAF = navigator.userAgent.match(/Safari\/[4-9]/);
            if(FF || MSIE || SAF) return true;
            return false;
        },
        popupEnabled: function() {
            var test = window.open('','','width=1,height=1,left=0,top=0,scrollbars=no');
            if(test){
                test.close();
                return true;
            }
            else return false;
        },
        /**
         *	Sends a request to the host, i.e, an instant message, status update, etc.
         *	@param { Object } transactionObject An object defined by the YAHOO.gaia.app.Gim.transactions.* methods with properties required by the transaction
         */
        requestData: function(transactionObject,skip) {
            var len = YAHOO.gaia.app.Gim.core.AIMData.length;
            transactionObject.timestamp = Date.parse(new Date());
            YAHOO.gaia.app.Gim.core.AIMData[len] = null;
            YAHOO.gaia.app.Gim.core.AIMData[len] = {};
            YAHOO.gaia.app.Gim.core.AIMData[len].oScript = document.createElement("script");
            YAHOO.gaia.app.Gim.core.AIMData[len].oScript.setAttribute("id","AIMBuddyList-AIMData-" + len);
            YAHOO.gaia.app.Gim.core.AIMData[len].oScript.setAttribute("type","text/javascript");
            YAHOO.gaia.app.Gim.core.AIMData[len].objData = transactionObject;
            if(skip != '1'){
                if(transactionObject.dataURI.indexOf("?") == -1) {
                    transactionObject.dataURI+="?r=" + len + "&nocache=" + Date.parse(new Date());
                } else {
                    transactionObject.dataURI+="&r=" + len + "&nocache=" + Date.parse(new Date());
                }

            }
            // YAHOO.gaia.app.Gim.core.debug("requestData: " + transactionObject.dataURI + "<br> Request-id AIMBuddyList-AIMData-" +len );
            //alert("requestData: " + transactionObject.dataURI);
            YAHOO.gaia.app.Gim.core.AIMData[len].oScript.setAttribute("src",transactionObject.dataURI);
            document.getElementsByTagName("head")[0].appendChild(YAHOO.gaia.app.Gim.core.AIMData[len].oScript);
        },
        
        startTimers: function() {
            var fn = function() {
                YAHOO.gaia.app.Gim.ui.updateCount();
                var blCookie = C.get(params.blopen);
                if(blCookie == "true") {
                    YAHOO.gaia.app.Gim.ui.updateBLMessage();
                    params.blWasOpen=true;
                    return;
                    //showLastMessage
                }
                
                if(params.autoLogin == 1) {
                    YAHOO.gaia.app.Gim.ui.updateMessageCount(params.blWasOpen);
                    params.blWasOpen=false;
                    return;
                    //showMessageCount
                }
               
            }
            window.setInterval(fn,5000);
        },

        /**
         *	Accepts all the incoming responses that result from requestData and routes them to the appropriate callback(s)
         *	@param { Object } json The JSON response from the host.
         */
        acceptData:function(json) {
            var requestId = parseInt(json.response.requestId);
            var code = parseInt(json.response.statusCode);
            if(code != 200) {
                try{
                    if(code == 401) {
                        var t = YAHOO.gaia.app.Gim.core.AIMData[requestId].objData.type;
                        // only these transactions expect a 401 - if we get it on any other, kill the session
                    }
                }
                catch(err) {
                    //YAHOO.gaia.app.Gim.core.debug("YAHOO.gaia.app.Gim.core.acceptData: Callback error! " + err.message + " (line " + err.line + ")");
                }
            }
            try{
                // YAHOO.gaia.app.Gim.core.debug("<b>YAHOO.gaia.app.Gim.core.acceptData:</b><br />" + json.response.toSource());
            } catch(err) { }
            var type = YAHOO.gaia.app.Gim.core.AIMData[requestId].objData.type;
            var fn = eval("params.callbacks." + type);
            var i = fn.length;
            while(i-- >0)	{
                try {
                    eval(fn[i] +"(json)");
                } catch(err) {
                    //YAHOO.gaia.app.Gim.core.debug("YAHOO.gaia.app.Gim.core.acceptData: Callback error! " + err.message + " (line " + err.line + ")")
                }
            }
            try {
                if(YAHOO.gaia.app.Gim.core.AIMData[requestId]) {
                    if(YAHOO.gaia.app.Gim.core.AIMData[requestId].oScript) {
                        YAHOO.gaia.app.Gim.core.AIMData[requestId].oScript.parentNode.removeChild(YAHOO.gaia.app.Gim.core.AIMData[requestId].oScript);
                    }
                }
            } catch(err) {
                //YAHOO.gaia.app.Gim.core.debug("YAHOO.gaia.app.Gim.core.acceptData: Unable to remove YAHOO.gaia.app.Gim.core.AIMData[" + requestId + "] -- " + err.message);
            }
        },
        /**
         *	Listens for event updates (i.e., a buddy signs off) from the host and routes to the appropriate callback(s)
         *	@param { Object } json The JSON response from the host.
         */
        listen:function(json) {
            
            
            var ePop = C.getSub(params.settingsCookies,"enablePopup");
            if(typeof(ePop) != 'undefined') {
                if (ePop == 1) {params.settings.enablePopup =1}
                if (ePop == 0) {params.settings.enablePopup =0}
            }
            
            if(json.response.statusCode == 460) {
                //if(params.loginAttempts > 2) return;
                //YAHOO.gaia.app.Gim.transactions.getSessionData(true);
                //params.loginAttempts++;
                return;
            }
            if(!json.response.data) return;
            YAHOO.gaia.app.Gim.core.destroyListenerObject(false);
            params.listenerURI = null
            params.listenerURI = json.response.data.fetchBaseURL + "&f=json&c=YAHOO%2Egaia%2Eapp%2EGim%2Ecore%2Elisten&timeout=" + params.REQUEST_TIMEOUT;
            if(json.response.data.events) {
                try {
                    //if(json.response.data.events.length > 0) ///YAHOO.gaia.app.Gim.core.debug("<b>YAHOO.gaia.app.Gim.core.listen:</b><br/>" + json.response.data.toSource());
                } catch(err) { }
                
                if(json.response.statusCode == 200) {
                    // YAHOO.gaia.app.Gim.core.debug(Util.dump(json.response.data.events));
                    json.response.data.events = json.response.data.events.reverse();
                    var i = json.response.data.events.length;
                    while(i-- > 0) {
                        if(json.response.data.events[i].type == 'sessionEnded'){
                            return;
                        }
                        var fn = eval("params.callbacks.listener." + json.response.data.events[i].type);
                        //YAHOO.gaia.app.Gim.core.debug(fn);
                        var j = fn.length;
                        while(j-- > 0) {
                            try {
                                var oResponse = json.response.data.events[i].eventData;
                                if(typeof(json.response.data.events[i].seqNum) !="undefined")
                                    oResponse.seqNum = json.response.data.events[i].seqNum;
                                eval(fn[j] +"(oResponse)");
                            } catch(err) {
                                YAHOO.gaia.app.Gim.core.debug("YAHOO.gaia.app.Gim.core.listen: Callback Error! " + err.message + " (line " + err.line + ")");
                            }
                        }
                    
                    }
                } 
             }
            YAHOO.gaia.app.Gim.core.requestInterval = setTimeout("YAHOO.gaia.app.Gim.core.destroyListenerObject(true)",json.response.data.timeToNextFetch);
        },

        /**
         *	Creates a script element that "listens" for event updates from the host.
         */
        createListenerObject:function() {
            clearTimeout(YAHOO.gaia.app.Gim.core.requestInterval);
            YAHOO.gaia.app.Gim.core.requestInterval = null;
            YAHOO.gaia.app.Gim.core.destroyListenerObject(false);
            var oListener = document.createElement("script");
            oListener.setAttribute("type","text/javascript");
            oListener.setAttribute("src", params.listenerURI + "&"  + Date.parse(new Date()));
            oListener.setAttribute("id","AIMListener");
            document.getElementsByTagName("body")[0].appendChild(oListener);
            // YAHOO.gaia.app.Gim.core.debug("AIMListener Script: "+params.listenerURI+"&"+Date.parse(new Date())+"'>");
        },
        /**
         *	Destroys the data container object that houses the script element that made the request and all data associated with it.
         *	@param { Variant } objIndex The index in the YAHOO.gaia.app.Gim.core.AIMData array that corresponds to the data to be destroyed. This is generally the requestId property of the JSON response
         */
        destroyDataObject:function(objIndex) {
            return; // this function causing FF to crash all of a sudden...I hate teh intarwebs
            try {
                if(YAHOO.gaia.app.Gim.core.AIMData[objIndex]) {
                    if(YAHOO.gaia.app.Gim.core.AIMData[objIndex].oScript) YAHOO.gaia.app.Gim.core.AIMData[objIndex].oScript.parentNode.removeChild(YAHOO.gaia.app.Gim.core.AIMData[objIndex].oScript);
                }
            } catch(err) { }
            YAHOO.gaia.app.Gim.core.AIMData[objIndex] = null;
        },
        /**
         *	Destroys the listener script object, and creates a new one if createNew is true.
         *	@param { Boolean } createNew Creates a new listener if true.
         */
        destroyListenerObject: function(createNew) {
            clearInterval(YAHOO.gaia.app.Gim.core.requestInterval);
            YAHOO.gaia.app.Gim.core.requestInterval = null;
            if(document.getElementById("AIMListener")) document.getElementById("AIMListener").parentNode.removeChild(document.getElementById("AIMListener"));
            if(createNew) YAHOO.gaia.app.Gim.core.createListenerObject();
        },
        /**
         *	Adds a callback to the callback object
         *	@param { Array } callbackObject The array that contains the callback functions for the event
         *	@param {String } newCallBack The name of the function to be called.
         */
        addCallback: function(callbackObject,newCallback) {
            callbackObject.push(newCallback);
        },
        /**
         *	Removes a callback from the specified callback array
         *	@param { Array } callbackObject The array that contains the callback function to be removed
         *	@param { String } oldCallback The callback to be removed
         */
        removeCallback: function(callbackObject,oldCallback) {
            callbackObject.splice(callbackObject.indexOf(oldCallback));
        },
        
        debug: function(str) {
            if(!params.DEBUG) return;
            if(typeof(params.debugWindow) == 'undefined' || params.debugWindow == null || params.debugWindow.closed) {
                params.debugWindow = null;
                params.debugWindow = window.open("","GIMDebug","status=1,toolbar=1,menu=1,resizable=1,height=400,width=500");
                var html = "<html><head></head><body><div></div></body></html>";
                params.debugWindow.document.write(html);
                params.debugWindow.document.close();
            }
            if(typeof(params.debugWindow) == 'undefined' || params.debugWindow == null || params.debugWindow.closed) return;
            var dbg = params.debugWindow.document.getElementById("AIMDebugger");
            if(!dbg) {
                dbg = params.debugWindow.document.getElementsByTagName("body")[0].appendChild(params.debugWindow.document.createElement("div"));
                D.setStyle(dbg,"overflow-y","auto");
                D.setStyle(dbg,"height","500px");
                dbg.setAttribute("id","AIMDebugger");
            }
            params.debugWindow.document.getElementById("AIMDebugger").innerHTML =  params.debugWindow.document.getElementById("AIMDebugger").innerHTML + "<p><span style=\"color:green;\">" + new Date() + "(" + Date.parse(new Date()) + ")</span><br/>" + str + "</p>";
            dbg.scrollTop = dbg.scrollHeight;
        }
        
    }
    
    YAHOO.gaia.app.Gim.transactions = {
        
        getSessionData: function(purge_cache) {
            C.setSub(params.forceGimAuth,"forceGimAuth",'0',{domain:document.domain,path:'/'});

            var URI = params.GAPI_URI;
            
            if(GAIA_config("main_server") == 'www.gaiaonline.com'){
                URI = params.GAPI_SECURE_URI;
            }

            var tObj = {
                dataURI: URI + params.transactions.getSessionData + "&purge_cache="+purge_cache+"&format=callback&c=YAHOO%2Egaia%2Eapp%2EGim%2Ecore%2EacceptData",
                type:"getSessionData"
            }
            
            YAHOO.gaia.app.Gim.core.requestData(tObj);
            
        },
            
        getGaiaBuddyList: function(){

            
            var callback = {

                success: function(o) {
                    if(typeof(o.responseText) == "undefined" || o.responseText == null || !o.responseText) return;
                    var tmpList  =  eval("(" + o.responseText + ")");
                    YAHOO.gaia.app.Gim.params.gFriendsList = tmpList;
                    tmpList = null;
                    YAHOO.gaia.app.Gim.transactions.getSessionData(false); //Do not purge cache for initial call
                    //console.log("success :"+U.dump(o));
                },
                failure: function(o) {
                    //console.log("failure :"+U.dump(o));
                },
                scope:this
                
            }

            var args = 'method=getinlinebuddylist';
            YAHOO.util.Connect.asyncRequest('POST',YAHOO.gaia.app.Gim.params.GAPI_URI,callback,args);

        }
        
    }

    YAHOO.gaia.app.Gim.ui = {
        
        storedBuddyInfo:[],
            
        createBuddyList: function(response) {

            var groupings = response.groups;
            var i = groupings.length;
            var group = null;

            while(i --> 0) {
                group = groupings[i];
                if(group.name == "All Gaia Friends"){
                    params.onlineCount=0;
                    var buddies = group.buddies;
                    var blen = buddies?buddies.length:0;
                    if(blen) buddies = buddies.reverse();
                    var j = blen;
                    while(j-- > 0){
                        params.friendslist[buddies[j].aimId] = buddies[j];
                    }
                    params.hasGaiaGroup= true;
                    YAHOO.gaia.app.Gim.ui.updateCount(true);
                }
            }
            params.blLoaded = true;
            
        },
            
        updateCount: function(recount) {
            
            if(typeof(recount) != "undefined" && recount) {
                var oCount = 0;
            
                for( var aimId in params.friendslist) {
                    if(params.friendslist[aimId].state == "online")
                        oCount++;
                }
                
                params.onlineCount = oCount;
            }
            
            var count = document.getElementById("GIMLaunch");
            if(count) {

                if(params.blWasOpen) {
                    count.innerHTML = 'Gaia IM (' + params.onlineCount + ')'; 
                }
                else{
                    count.innerHTML = 'Buddy List (' + params.onlineCount + ')';
                }
                count.setAttribute('alt',params.onlineCount + ' friends online');
                count.setAttribute('title',params.onlineCount + ' friends online');
            }

        },

        updateBuddyList: function(response) {

            if(typeof(response.aimId) != "undefined") {
                params.friendslist[response.aimId].state = response.state;
                YAHOO.gaia.app.Gim.ui.updateCount(true);
                
            }

            

        },

        scrollNotification : function (){ 

            if(params.temp_count == params.seqCookies.mCount) return;

            if(params.HEADER_MESSAGE == ""){
                return;
            } 
            params.HEADER_MESSAGE = params.HEADER_MESSAGE.substring(1, params.HEADER_MESSAGE.length) + params.HEADER_MESSAGE.substring(0, 1);

            document.title = params.HEADER_MESSAGE;
            params.SCROLL_TIMEOUT = window.setTimeout("YAHOO.gaia.app.Gim.ui.scrollNotification()", 200);
            E.addListener(window,'focus', function(){if(params.HEADER_MESSAGE == "") return;params.HEADER_MESSAGE= ""; document.title = params.OLD_HEADER; clearInterval(params.SCROLL_TIMEOUT);params.temp_count = params.seqCookies.mCount;
});
        },
            
    
        acceptIncomingMessage: function(response){
            
            //Show bubble setting is turned off, return and dont display
            if(params.settings.showBubble == '0') return;
            var aimId = response.source.aimId;
    
            //reject those without @gaiaonline.com and not the bot  and not a friend.
            if(aimId.indexOf('@gaiaonline.com') == -1 && aimId != 'gaiaguildbot' && typeof(params.friendslist[aimId]) == 'undefined') return;            
            if(response.seqNum <= params.seqCookies.lastNum && response.timestamp <= params.seqCookies.lastTime) {
                return;
            }
            else{
                var now = new Date();
                now.setSeconds(now.getSeconds()+300);
                params.seqCookies.lastNum = response.seqNum;
                params.seqCookies.lastTime = response.timestamp;
                params.seqCookies.mCount++;
                C.setSubs(params.seqKey,params.seqCookies,{domain:document.domain,path:'/'});
            }


            if(typeof(params.friendslist) == "undefined" || typeof(params.friendslist[aimId]) == "undefined"){
                if(params.blLoaded && !params.hasGaiaGroup) {
                    params.glauncher.launchUser("",true,"true");
                    params.hasGaiaGroup = true;
                }
                return;
            }
            
            if(params.settings.enablePopup && !params.blWasOpen){
                params.glauncher.launchUser(aimId,true,"false");
            }
        },

        
        updateMessageCount: function(blWasOpen) {
   
            var nHeader = document.getElementById('AIMBuddyListNotifierHeader');
            nHeader.setAttribute("timestamp",params.seqCookies.lastTime);
            var iContainer = document.getElementById("AIMNoticeIconContainer");
            if(iContainer) {
                E.purgeElement(iContainer,true);
                iContainer.parentNode.removeChild(iContainer);
                iContainer = null;
            }
        
            if(blWasOpen) {
                params.seqCookies = C.getSubs(params.seqKey);
                if(!params.seqCookies ) {
                    params.seqCookies={lastNum:0,lastTime:0,mCount:0};
                }
                params.seqCookies.mCount=0;
            }
            if(params.seqCookies.mCount < 1){
                D.setStyle(nHeader,"display","none");
                if(typeof(params.SCROLL_TIMEOUT) != 'undefined') {
                    clearTimeout(params.SCROLL_TIMEOUT);
                }
                return;
            }
            iContainer = document.createElement("div");
            iContainer.setAttribute("id",'AIMNoticeIconContainer');
            nHeader.appendChild(iContainer);
            
           
           
           
            if(navigator.userAgent.match(/MSIE [6-9]/)) {
                var img = document.createElement("div");
                D.setStyle(img,"background",'0');
                D.setStyle(img,"filter","progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+params.CHAT_ICON+"', sizingMethod='scale')");
                D.setStyle(img,'height','30px');
                D.setStyle(img,'width','30px');
                //img.setAttribute('src',params.BLANK_ICON);
            }
            else{
                var img = document.createElement("img");
                img.setAttribute('src',params.CHAT_ICON);
                img.setAttribute('height','30');
                img.setAttribute('width','30');
            }
            
            D.addClass(img,'AIMNoticeIconImage');
            
            
            iContainer.appendChild(img);
            
            var mContainer = document.getElementById("AIMNoticeMsgContainer");
            if(mContainer) {
                mContainer.parentNode.removeChild(mContainer);
                mContainer = null;
            }
                   
            mContainer = document.createElement("div");
            mContainer.setAttribute("id","AIMNoticeMsgContainer");
            nHeader.appendChild(mContainer);
            var uName = document.createElement("div");
            
            dName="";
            D.addClass(uName,"AIMNoticeMsgName");
            uName.setAttribute('id','closeNotice');
            uName.innerHTML="<br>";
            mContainer.appendChild(uName);
            var uMess = document.createElement("div")
            D.addClass(uMess,"AIMNoticeMsg");

            uMess.innerHTML = "You have "+params.seqCookies.mCount+" message"+ (params.seqCookies.mCount > 1?"s":"") ;
            mContainer.appendChild(uMess);

            D.setStyle(nHeader,"display","block");

            params.HEADER_MESSAGE = 'Gaia Online - ' + 'You have ' + params.seqCookies.mCount + ' message' + (params.seqCookies.mCount > 1?"s":"") +' --';
            clearTimeout(params.SCROLL_TIMEOUT);
            YAHOO.gaia.app.Gim.ui.scrollNotification();
            var aimId="";
            E.addListener(nHeader,'mousedown',function(){
                                  D.setStyle(nHeader,"display","none");
                                  params.glauncher.launchUser(aimId,true,"false");
                                  if(typeof(params.SCROLL_TIMEOUT) != 'undefined') {
                                      clearTimeout(params.SCROLL_TIMEOUT);
                                  }
                                  params.seqCookies.mCount=0;
                                  E.removeListener(nHeader,'mousedown');
                                  
                              });
      
        },

        updateBLMessage: function() {
            
            var nHeader = document.getElementById('AIMBuddyListNotifierHeader');
            var blItems = C.getSubs(params.blmessage);
            if(blItems) {
                var mDate = new Date(blItems.lastTime);
                var now = new Date();
                
                var oldTime = nHeader.getAttribute("timestamp");
                
                if(now < mDate.setMinutes(mDate.getMinutes() + params.pollingInt) && oldTime != blItems.lastTime){
                    nHeader.setAttribute("timestamp",blItems.lastTime);
                    var iContainer = document.getElementById("AIMNoticeIconContainer");
                    if(iContainer) {
                        iContainer.parentNode.removeChild(iContainer);
                        iContainer = null;
                    }
                    
                    iContainer = document.createElement("div");
                    iContainer.setAttribute("id",'AIMNoticeIconContainer');
                    nHeader.appendChild(iContainer);
                    var img = document.createElement("img");
                    img.setAttribute('src',blItems.lastIcon);
                    img.setAttribute('height','30');
                    img.setAttribute('width','30');
                    D.addClass(img,'AIMNoticeIconImage');
                    iContainer.appendChild(img);

                    var mContainer = document.getElementById("AIMNoticeMsgContainer");
                    if(mContainer) {
                        mContainer.parentNode.removeChild(mContainer);
                        mContainer = null;
                    }
                    
                    mContainer = document.createElement("div");
                    mContainer.setAttribute("id","AIMNoticeMsgContainer");
                    nHeader.appendChild(mContainer);
                    var uName = document.createElement("div");
                    D.addClass(uName,"AIMNoticeMsgName");
                    uName.setAttribute('id','closeNotice');
                    uName.appendChild(document.createTextNode(blItems.lastBuddy + ": "));
                    mContainer.appendChild(uName);
                    var uMess = document.createElement("div");
                    D.addClass(uMess,"AIMNoticeMsg");

                    //msg = blItems.lastMessage.replace(/^[0-9a-zA-Zs]+$/g,"");
                    //msg = msg.replace(/&#160;/g,"");
                    var msg = blItems.lastMessage.replace(/(&#160;|&#160||&|#)/g,"");
                    uMess.appendChild(document.createTextNode(msg));
                    mContainer.appendChild(uMess);
                    
                    D.setStyle(nHeader,"display","block");
                    // Event.addListener('closeNotice','click',function(){Dom.setStyle(nHeader,"display","none"); });
                    params.glauncher.init({gUserId: params.gUserId});
                    E.addListener(nHeader,'mousedown',function(){
                                          D.setStyle(nHeader,"display","none");
                                          params.glauncher.launchUser(blItems.lastBuddyId,true,"true");
                                          if(typeof(params.SCROLL_TIMEOUT) != 'undefined') {
                                               clearTimeout(params.SCROLL_TIMEOUT);
                                           }
                                          E.removeListener(nHeader,'mousedown');
                                              });

                    params.HEADER_MESSAGE = 'Gaia Online - ' + 'You have a message from ' + blItems.lastBuddy +' --';
                    clearTimeout(params.SCROLL_TIMEOUT);
                    YAHOO.gaia.app.Gim.ui.scrollNotification();
                }
            }
            else {
                D.setStyle(nHeader,"display","none");
                 if(typeof(params.SCROLL_TIMEOUT) != 'undefined') {
                    clearTimeout(params.SCROLL_TIMEOUT);
                }
            }
        },

         /**
         *	Replaces emoticons with images, i.e., :) becomes smile.png
         *	@param { String } txt The text to have the regexp permformed on
         *	@return { String} the modifed string
         */
		addEmoticons: function(txt) {
			if(params.USE_EMOTICONS) {
				for(var y = 0; y < params.emoticons.length; y++) {
					var emoticon = params.emoticons[y];
					for (var x = 0; x < emoticon.code.length; x++) {
						var code = emoticon.code[x];
						txt = txt.replace(code,'<img src="'+params.EMOTICON_URI+emoticon.path+'" />','g');
					}
				}
			}
			return txt;
		},
            
        updateTypingStatus: function(json){return;}

    }

    YAHOO.gaia.app.Gim.callbacks = {
        //Get session data and populate and try to send to listener object
        getSessionData: function(json) {
            //YAHOO.gaia.app.Gim.core.debug('getSessionCallback :' + U.dump(json));
            if(json.response.statusCode == 200){
                params.gSecret = json.response.gsecret;
                params.seqKey = json.response.sequence_key;
                params.listenerURI = json.response.fetchBaseURL + "&f=json&c=YAHOO%2Egaia%2Eapp%2EGim%2Ecore%2Elisten&timeout=" + params.REQUEST_TIMEOUT;
                                    
                YAHOO.gaia.app.Gim.core.destroyListenerObject(true);
            }
        }
    
    }

         
})();
   


YAHOO.namespace("gaia.util");

/**
 * A port of PHP's print_r for getting a detailed output on an object
 * @param {Object} arr an Array / Hash / Object to analyze
 * @param {Int} level the level to scan [optional]
 * @return {String} the var dump structure
 **/
YAHOO.gaia.util.dump = function (arr,level) {
    var dumped_text = "";
    if (!level) {
        level = 0;
    }

    //The padding given at the beginning of the line.
    var level_padding = "";
    for (var j=0; j<level + 1; j++) {
        level_padding += "    ";
        if (level > 5) {
            level_padding += '...';
            return level_padding;
        }
    }

    // arrays hashes and objects
    if (typeof(arr) == 'object') {
        for (var item in arr) if (YAHOO.lang.hasOwnProperty(arr, item)) {
            var value = arr[item];
 
            if(typeof(value) == 'object') {
                // recursion occurs here because it is an object / hash / etc
                dumped_text += level_padding + "'" + item + "' ...\n";
                dumped_text += YAHOO.gaia.util.dump(value,level+1);
            }
            else {
                // does not have anything deeper at that point
                dumped_text += level_padding + "'" + item + "' => ("+typeof(value)+") \"" + value + "\"\n";
            }
        }
    }
    else {
        // strings, etc are all output normally
        dumped_text = "("+typeof(arr)+") \"" + arr + "\"";
    }

    return dumped_text;
};

YAHOO.gaia.util.popupEnabled = function() {

    var test = window.open('','','width=1,height=1,left=0,top=0,scrollbars=no');
    if(test){
        test.close();
        return true;
    }
    else {
        return false;
    }
       
};

YAHOO.namespace("gaia.app.Gim");
(function() {

    var Dom = YAHOO.util.Dom,
        Event = YAHOO.util.Event,
        Cookie = YAHOO.util.Cookie,
        Util = YAHOO.gaia.util;
        

YAHOO.gaia.app.Gim.Launcher = function() {
    this._gUserId = null;
    this._cookies = null;
    this._path = null;
    this._domain = null;
    this._gUrl= null;
    this._nContainerId = null;
    this._lLaunchLink = null;
    this._nPollingInt = null;
    this._cOName = null;
    this._cFName = null;
    this._cMName = null;
    this._cSName = null;
    this._blHeaderTimer = null;
    this._gimSetup = true;
    this._DEBUG = false;
    this._debugWindow = null;
    this._opening = false;
    this._showtoolbar = false;
    this._store = null;
    this._autoLogin = true;    
};

YAHOO.gaia.app.Gim.Launcher.prototype.init = function(settings){

   
    this._gUserId = settings.gUserId;
    this._cookies = {
        blfocus: settings.blfocus || 'blfocus',
        blopen:  settings.blopen || 'blopen',
        blmessage: settings.blmessage || 'blmessage',
        settingscookies: settings.settingscookies || 'settingsCookies',
        subpopupwarned: settings.subpopupwarned ||'popupwarned',
        subsessionclosed: settings.subsessionclosed || 'sessionClosed'
                     }
    var gaiaUrl = 'http://' + GAIA_config("main_server") + '/gim';
    this._path = settings.path ? settings.path : '/';
    this._domain = settings.domain ? settings.domain : document.domain;
    this._gUrl = settings.url ? settings.gUrl : gaiaUrl;
    this._nContainerId = settings.nContainer ? settings.nContainer : 'AIMBuddyListNotifierHeader';
    this._lLaunchLink = settings.lLaunchLink ? settings.lLaunchLink : 'GIMLaunch';
    this._nPollingInt = settings.nPollingInt ? settings.nPollingInt : 5;    
    this._cOName = this._gUserId + '_' + this._cookies.blopen;
    this._cFName = this._gUserId + '_' + this._cookies.blfocus;
    this._cMName = this._gUserId + '_' + this._cookies.blmessage;
    this._cSName = this._gUserId + '_' + this._cookies.settingscookies;
    this._gimSetup = settings.gimSetup;
    this._showtoolbar = settings.showtoolbar;
    if(typeof(settings.autoLogin) != "undefined" && settings.autoLogin == 0){
        this._autoLogin = false;
    }

    if(this._gimSetup != 1) {
        var headID = document.getElementsByTagName("head")[0];         
        var newScript = document.createElement('script');
        newScript.type = 'text/javascript';
        newScript.src = "http://" +  GAIA_config("graphics_server") + "/src/js/gim/setup/setup.js";
        headID.appendChild(newScript);
    }

    
    YAHOO.util.Event.addListener(this._lLaunchLink,"click",this.listLaunch,this,true);

 
 
    var blCookie = Cookie.get(this._cOName);

    if(settings.enablePopup == 1 && blCookie != 'true' && this._gimSetup > 0 && settings.validated > 0 && settings.user_tos_status > 0 && settings.disable_gim_popup == 0 ){
        this.listLaunch();
        window.focus();
    }

    YAHOO.gaia.app.Gim.widgets.header.launch(settings);

};


YAHOO.gaia.app.Gim.Launcher.prototype.listLaunch = function(ev,override) {
    //document.getElementById('GIMLaunch').innerHTML = 'Gaia IM';
    if(!this._gimSetup) return;

    //this._store.get('testdata',function(ok,val) {alert('some_key=' + val)});
    var isClick = false;
    if(typeof(ev) != 'undefined'){
        if((typeof(ev.type) != 'unknown' && ev.type == "click") || override == true){
            isClick = true;
        }
    }

    if(!isClick) {
        var sStatus = Cookie.getSub(this._cSName,this._cookies.subsessionclosed);
         if(sStatus != null && sStatus == "true" ) {
             return;
         }
    }
    var blCookie = Cookie.get(this._cOName);
    // if buddy list open
    if(blCookie == 'true') {
        var now = new Date();
        now.setSeconds(now.getSeconds + 5);
        Cookie.set(this._cFName,'true',{path:"/",domain:document.domain});
    }
    else{
        if(this._opening) return;
        this._opening = true;

        if(this._showtoolbar == 1) {
            var w = window.open(this._gUrl, "buddylist", "toolbar=yes,location=yes,status=no,menubar=yes,scrollbars=no,width=275,height=480,resizable");
        }
        else {
            var w = window.open(this._gUrl, "buddylist", "toolbar=no,location=no,status=no,menubar=no,scrollbars=no,width=275,height=480,resizable");
        }
        if(!w) {
            var warned = Cookie.getSub(this._cSName,this._cookies.subpopupwarned);
            if(warned == null || warned != "true" || isClick) {
                var now = new Date();
                now.setHours(now.getHours() + 24);
                Cookie.setSub(this._cSName,this._cookies.subpopupwarned,'true',{path:"/",domain:document.domain,expires:now});
                alert("The browser you are using is disabling pop-ups from this site, for full functionality of the Gaia instant Messenger please enable pop-up windows from Gaia");
                   
            }
            this._opening = false;
            return;
            
              
        }
        else {
            var now = new Date();
            now.setSeconds(now.getSeconds()+10);
            Cookie.set(this._cOName,'true',{domain:document.domain,path:'/',expires:now});
            w.focus();
        }
        var scope = this;
        window.setTimeout(function(){ scope._opening=false},5000);
    }
    
};



YAHOO.gaia.app.Gim.Launcher.prototype.updateBLHeader = function(){
    var scope = this;
    var fn = function(){
        var blCookie = Cookie.get(scope._cOName);
        var nHeader = document.getElementById(scope._nContainerId);
        if(blCookie == 'true') {
            
            var blItems = Cookie.getSubs(scope._cMName);
            if(blItems) {
                var mDate = new Date(blItems.lastTime);
                var now = new Date();
                var oldTime = nHeader.getAttribute("timestamp");
                if(now < mDate.setMinutes(mDate.getMinutes() + scope._nPollingInt) && oldTime != blItems.lastTime){
                    nHeader.setAttribute("timestamp",blItems.lastTime);
                    var iContainer = document.getElementById("AIMNoticeIconContainer");
                    if(iContainer) {
                        iContainer.parentNode.removeChild(iContainer);
                        iContainer = null;
                    }
                    
                    iContainer = document.createElement("div");
                    iContainer.setAttribute("id",'AIMNoticeIconContainer');
                    nHeader.appendChild(iContainer);
                    var img = document.createElement("img");
                    img.setAttribute('src',blItems.lastIcon);
                    img.setAttribute('height','30');
                    img.setAttribute('width','30');
                    Dom.addClass(img,'AIMNoticeIconImage');
                    iContainer.appendChild(img);

                    var mContainer = document.getElementById("AIMNoticeMsgContainer");
                    if(mContainer) {
                        mContainer.parentNode.removeChild(mContainer);
                        mContainer = null;
                    }
                    
                    mContainer = document.createElement("div");
                    mContainer.setAttribute("id","AIMNoticeMsgContainer");
                    nHeader.appendChild(mContainer);
                    var uName = document.createElement("div");
                    Dom.addClass(uName,"AIMNoticeMsgName");
                    uName.setAttribute('id','closeNotice');
                    uName.appendChild(document.createTextNode(blItems.lastBuddy + ": "));
                    mContainer.appendChild(uName);
                    var uMess = document.createElement("div");
                    Dom.addClass(uMess,"AIMNoticeMsg");

                    //msg = blItems.lastMessage.replace(/^[0-9a-zA-Zs]+$/g,"");
                    //msg = msg.replace(/&#160;/g,"");
                    var msg = blItems.lastMessage.replace(/(&#160;|&#160||&|#)/g,"");
                    uMess.appendChild(document.createTextNode(msg));
                    mContainer.appendChild(uMess);
                    
                    Dom.setStyle(nHeader,"display","block");
                    // Event.addListener('closeNotice','click',function(){Dom.setStyle(nHeader,"display","none"); });
                    var glauncher = new YAHOO.gaia.app.Gim.GlobalLauncher(); 
                    glauncher.init({gUserId: scope._gUserId});
                    Event.addListener(nHeader,'click',function(){
                                          Dom.setStyle(nHeader,"display","none");
                                          glauncher.launchUser(blItems.lastBuddyId,true,"false")
                                              });
                }
            }
            else {
                Dom.setStyle(nHeader,"display","none");
            }
        }
        else{
            //   Dom.setStyle(nHeader,"display","none");
        }
                     
    };
    scope._blHeaderTimer = window.setInterval(fn,5000);

};


YAHOO.gaia.app.Gim.Launcher.prototype.debug = function(str) {

    if(!this._DEBUG) return;
    
    if(this._debugWindow == null || this._debugWindow.closed) {
        this._debugWindow = window.open("","HeaderDebug","status=1,toolbar=1,menu=1,resizable=1,height=400,width=500");
        var html = "<html><head></head><body><div></div></body></html>";
        this._debugWindow.document.write(html);               
    }
    var dbg = this._debugWindow.document.getElementById("AIMDebugger");
    if(!dbg) {

        dbg = this._debugWindow.document.getElementsByTagName("body")[0].appendChild(this._debugWindow.document.createElement("div"));
        Dom.setStyle(dbg,"overflow-y","auto");
        Dom.setStyle(dbg,"height","500px");
        dbg.setAttribute("id","AIMDebugger");
               
    }
    this._debugWindow.document.getElementById("AIMDebugger").innerHTML =  this._debugWindow.document.getElementById("AIMDebugger").innerHTML + "<p><span style=\"color:green;\">" + new Date() + "(" + Date.parse(new Date()) + ")</span><br />" + str + "</p>";
    this._debugWindow.document.close();
            //dbg.scrollTop = dbg.scrollHeight;

};

})()


YAHOO.namespace("gaia.app.Gim");
(function() {

    var Cookie = YAHOO.util.Cookie;


    YAHOO.gaia.app.Gim.GlobalLauncher = function() {

        this._cookies = null;
        this._gUserId = null;

    };


    YAHOO.gaia.app.Gim.GlobalLauncher.prototype.init = function(settings) {
        

        this._gUserId = settings.gUserId;
        this._gUrl = "/gim";
        this._cookies = {
            blstartconvo : (settings.blfocus || 'blstartconvo'),
            blopen : (settings.blopen || 'blopen')
        };


        this._cStartConvoId =  this._gUserId + '_' + this._cookies.blstartconvo;
        this._cOpenId = this._gUserId + '_' + this._cookies.blopen;
        
        
        
    };

    YAHOO.gaia.app.Gim.GlobalLauncher.prototype.launchUser = function(userId,useAimId,focus) {
        var blCookie = Cookie.get(this._cOpenId,{path:"/",domain:document.domain});

        if(blCookie != 'true') {
            var w = window.open(this._gUrl, "buddylist", "toolbar=no,location=no,status=no,menubar=no,scrollbars=no,width=600,height=480,resizable");
            w.focus();
        }
        else {
            focus="true";
        }
  
        var now = new Date();
        if(typeof(useAimId) == 'undefined')
            useAimId = false;
        if(typeof(focus) == 'undefined')
            focus = true;

        var items = {gUserId:userId,timestamp:now,useAimId:useAimId,focus:focus};
        now.setSeconds(now.getSeconds() + 5);
        Cookie.setSubs(this._cStartConvoId,items,{path:"/",domain:document.domain});
        
    };

})();
