


/******************************************************************************************
         publicbooks.js
 ******************************************************************************************/

/*

	Book Data Structure:

*/

Ext.BLANK_IMAGE_URL = '../js/extjs/resources/images/default/s.gif';
Ext.namespace('pb');


gMessenger=function(){this.addEvents();}		//--- make a global event messenger, usage:
Ext.extend(gMessenger, Ext.util.Observable);	// gMsg.on('eventName', function(evtObj){})
gMsg=new gMessenger();							// gMsg.fireEvent('eventName', evtObj);


pb=function() {
	/* ------------------------------------------------- PRIVATE VARS AND FUNCTIONS ---- */
	var whoami="pb"


	/* --------------------------------------------------- START PUBLIC SPACE ------------ */
	/* 								( containts public properties and methods )            */
  	return {
											
	whoami: 'pb.public',
	folderTree: {},
	vyewport: 0,
	bookStore: 0,
	folderLevelsExpanded: 2,
	loadVyewletDelay: 0, 		//ms to wait to load vyewlet



	/**
	 * ------------------------------------------------------------------------------------ 
	 *		INIT 
	 * ------------------------------------------------------------------------------------ 
	 */
	init: function() {
		var sid=getCookie('sid');
		if(sid && sid.length>3){
			this.init1();
		}else{
			vyew.php.call("VyewSettings.genSession",[], 
			function(res){
				if(res && res.length>5){
					setCookie('sid',res)
					this.init1();
				}
			}.createDelegate(this));
		}
	},
	init1: function() {
		try{
		this.origMainFrameUrl=this.getMainFrame().location.href
		}catch(e){throw new Error('Err9801:Side frame not being run within frameset');}
		SWFAddress.onChange=function() {
			this.parseMID();	
		}.createDelegate(this);
		this.parseMID();
	},

	init2: function() {
        this.initLayout();
		this.initController();
        this.loadPublicBooks();       
		if(this.loadVyewletDelay>0){
			if(this.getMID().bid){
				setTimeout(function(){
					this.openBook(this.getMID().mid);
					//this.presetTreeNode(this.getMID().bid);
				}.createDelegate(this),this.loadVyewletDelay);
			}else openRightFrame("pub.aboutvyew.html");
		}
        vyew.checkLogin();
	},

	/**
 	 * Checks for mid/book/fid in url, looks up customID then loads it
	 */
	parseMID: function()
	{
		//--- dont run this if it was just run a second ago
		if(getTimer()-this.lastAddrChg<=1) return;
		this.lastAddrChg=getTimer();
		var rmid=urlSegment("#",parent);
		if(!rmid && !(rmid.length > 1)){
			throw new Error('Err9802: No M.I.D. found');
			this.init2();
			return;
		}
		//--- breakup mid
		if(rmid.match(/[\/_]/)){
			try {
				rmid=rmid.replace(/\//g,'_');
				rmid=rmid.match(/[^0-9a-zA-Z]*(.*)/)[1];
			} catch(e) { throw new Error('Err983: Cant regex MID'); }
		}
		if(rmid==this.current_rmid) return;
		this.current_rmid=rmid
		vyew.php.call("VyewMain.lookupMeeting",[getCookie('sid'),this.current_rmid],
				function(res){
					this.current_mid=res.meetingID;
					if(this.loadVyewletDelay==0){
						if(this.getMID().bid){ 
							this.openBook(this.getMID().mid)
							//this.presetTreeNode(this.getMID().bid);
						} else openRightFrame("pub.aboutvyew.html");
					}
					this.init2();
				}.createDelegate(this))
	},
	lastAddrChg:0,


	/**
	 * Sets the selected tree node to the currently opened VyewBook in Vyewlet
	 * @param bid {number} - BookID
	 */
	presetTreeNode: function(bid)
	{
		if(bid==null) bid=this.getMID().bid;
		if(!bid) return;
		var n=this.getFolderNodeById(bid);	
dbg('presettree',bid,this.folderTree,n)
		if(!n) return;
		var rCount=0;
		var parentN = n.parentNode;
		while(parentN){
		   parentN.expand();
		   parentN=parentN.parentNode;
		   rCount++;
		   if(rCount>10) break;
		}
		n.select()	
	},

	/* ---------------------------------------  LAYOUT -----------------------------*/

	initLayout: function() {
												//--- init viewport, and make shortcut links
		this.vyewport = new pb.Vyewport({id:'mainVyewport'}); 
		//this.vyewbookGrid = this.myvyewbooksPanel.items.itemAt(1);
		//this.bookStore = this.vyewbookGrid.getStore();
		this.folderTree = this.vyewport.findById('folderTree');
		if(this.vyewport.rendered){
			this.onVyewportRendered();
		}else{
			this.vyewport.on({render:{ fn:this.onVyewportRendered, scope:this, delay: 200}});
		}
	},

	onVyewportRendered: function() {
		//this.setLogo('img/publogo-'+this.getMID().baseMID+'.jpg');
		//window.document.write('<link rel="stylesheet" type="text/css" href="../css/stanford.css" />');
		this.loadUserdefPanel('toppanel');
		this.loadUserdefPanel('botpanel');
	},

	loadUserdefPanel: function(id) {
			Ext.Ajax.request({
                url: 'public.'+id+'.'+this.getMID().baseMID+'.html',
                success: function(res, id){
                    if(res.responseText && res.responseText.length > 5){

						//var height=parseInt(res.responseText.match(/panelheight:([0-9]*)/)[1])
						//height = (height > 1) ? height : 50;

                        var bp=this.vyewport.findById(id);
						var siz=bp.getSize();
                        bp.body.update(res.responseText);
					
						var sh=parseInt(bp.body.dom.scrollHeight);
						if(sh>10) h=sh;
						else h=parseInt(res.responseText.match(/panelheight:([0-9]*)/)[1])

                        bp.setSize({height:h});
                        bp.ownerCt.doLayout();
                    }
                }.createDelegate(this,[id],1)
            });
	},

	setLogo: function( url ) {
		var lp=this.vyewport.findById('toppanel');
		if (url){
			lp.setSize({height:50});
			lp.body.update('<center><img id="logoimg" src="' + url + '" border=0></center>');
			if (Ext.get("logoimg").dom.width < 30) return this.setLogo(false);
		}else{
			lp.setSize({height:0}); }
		lp.ownerCt.doLayout();
	},



	/*			CCCCCCCCCC  TTTTTTTTTTT  LLL
				CCCCCCCCCC	TTTTTTTTTTT  LLL
				CCC				TTT		 LLL
				CCC				TTT		 LLL
				CCC				TTT		 LLL
				CCC				TTT		 LLL
				CCCCCCCCCC		TTT		 LLLLLLLLLLL
				CCCCCCCCCC		TTT		 LLLLLLLLLLL
	*/

	/* ------------------------------- CONTROLLER: BUTTON/EVENT HANDLING (ctl)-------------- */

	initController: function() {

								/* ------------- TREE EVENTS -------------- */
		gMsg.on('treeEvent', function(e){ //e:{id,node}
            switch(e.id){
				case "selectfolder":
					//this.updateGrid(e.node.attributes.ID);
					if( e.node.attributes.type=="book" ) {
						//todo--does this need doing anything? maybe should be set in openbook
						//this.current_mid=e.node.attributes.meetingID;
						//this.current_bid=e.node.id;
						this.openBook( e.node.attributes.meetingID, e.node.attributes );
					}
					break;

				case "duplicatebook":
					setCookie('pub.dupbook',this.getMID().bid,"session");
					if( vyew.ud && vyew.ud.type=="REGISTERED" && getCookie('noDupNotice')=='1' ){
						openRightFrame("pub.dupbook.html");
					}else{
						openRightFrame("stanford.login.html");
					}
					break;

				case "onrender":
					this.presetTreeNode();
					break;
 
			}//sw
		},this);
	},


	/**
	 * Loads book into Vyewlet, and sets URL Hash address
	 * @param mid {string} - Full numeric Meeting ID ("1234_5678")
	 */
	openBook: function(mid, bookinfo){
		try{
			var bid=bookname=mid.match(/_(.*)/)[1];
		}catch (e) {
			throw new Error('VyewError884: cant parse mid');
			return;
		}

		var mObj=this.getMID();
		if(bookinfo && bookinfo.name){
			this.current_bookinfo=bookinfo;
			bookname=bookinfo.name.replace(/ /g,'_');
		}else{
			bookname=mObj.bookname;
		}
		if(!bookname)bookname=bid;
		this.current_mid=mid;		
		this.current_rmid=mObj.customID+"_"+bookname;
		this.lastAddrChg=getTimer();
		top.location.hash="/"+mObj.customID+"/"+bookname;

    	//this.getRootFrame().closeFrame();
		var baseurl=this.origMainFrameUrl;
		var url=baseurl+"?mid="+mid;
		if (!this.getMainFlash()) {
			this.getMainFrame().location = url;
    	} else {
			this.getMainFlash().ajaxApi({cmd:'loadBook',bid:bid,mid:mid});
		}
		
		//--- if right frame is open, close it and reset location
		if(isRightFrameOpen()){
			closeRightFrame();	
			parent.rightframe.location="blank.html";
		}
		return;
		if(isRightFrameOpen()){
			if(parent.rightframe.location.href.match(/pub\.dupbook/)){
				parent.rightframe.location=parent.rightframe.location.href;
			}else
				closeRightFrame();
		}
	},

	btnInvite: function(bid) {
    	var n = bookStore.getAt(bookStore.find("id",bid)).get("name")
    	n = (n ? n : "...");
    	$("#dg_invite #bid").attr("value",bid);
    	$("#dg_invite").dialog({draggable:true, height:170,
        	    width:300, resizable:false, title:"Invite to "+n, modal:"true"
        	});
	},











	/* ------------------------------------------ DATA LOADING ------------------------ */
	loadPublicBooks: function()
	{
        vyew.php.call("LayerCollection.getPublicBooks", ["skippy",this.getMID().baseMID],
        function(res)
        {
            //process books into real arrays
            vyew.od.books=[];       //json format: [{id,name,owner,pageCount},{id,name...},...]	
            vyew.od.booksArrays=[]; //array format: [[0,'name','tim',33],[1,'name2',...],...]

									//tree format: { children:[{id, text, children:[]},{...}] }
			vyew.od.folderNodes={id:'0', text: 'My Vyewbooks', expanded: true, 
								allowDrag:false, children:[]};  
			this.processFolders(res.books.folders, vyew.od.folderNodes);

            for(var i in res.books){
                bk=res.books[i];
                if(bk.name){
                    vyew.od.books.push(bk);
                    vyew.od.booksArrays.push([bk.id,bk.name,bk.ext,bk.owner,bk.pageCount,
							bk.lastEdit,bk.isPublic,
                          	bk.meetingID,bk.canInvite,bk.publishedFrom,
							bk.ownerID,bk.isPublished,
                           	bk.invitees,bk.activity_view,bk.folderID,'test1',''])

	            	bk.type="book";
					bk.text=bk.name;
					bk.cls='x-tree-book-icon';
					bk.leaf=true;
    	    	    var f = this.findFolder(bk.folderID);
        		    f = f ? f : vyew.od.folderNodes;
    	        	f.children.push(bk);
                }
            }

			//this.addBooksToFolderTree(res.books, vyew.od.folderNodes);
//        	this.bookStore.loadData(vyew.od.booksArrays)
//			this.updateGrid();	
			this.initTree();           
        }.createDelegate(this));
	},//loadBooks	


	
	// Processes flat array of folders from server into tree structure
	// folderNodes is actually a reference to vyew.od.folderNodes
	processFolders: function(rawFolders, folderNodes) 
	{		
		if(!rawFolders instanceof Array || rawFolders.length < 1) return [];

		//--- Change text to ints, rename vars as needed, set default node config
		for (var i in rawFolders){
			var fold=rawFolders[i];
			if(!fold.parentID){ if(fold.name && fold.name.length > 1) fold.parentID=0;
                          else continue; }
			if(!rawFolders.findObj('ID', fold.parentID)) fold.parentID=0;
			fold.ID=parseInt(fold.ID);
			fold.id=""+fold.ID;	//force a string so that folderID becomes nodeID
			fold.parentID=parseInt(fold.parentID);
			fold.text=fold.name;
			fold.singleClickExpand=true;
			fold.leaf=false;
			//fold.expanded=true;
		}

		this.putFoldersIntoParent( rawFolders, folderNodes );
	},

	
	// Recursively find all folders whos parentID = currentFolderObj.ID, and add them as children
	putFoldersIntoParent: function( rawFolders, currentFolderObj, recurs )
	{
		if(!recurs)recurs=0; 
		recurs++;
		if(recurs>20) return;
		var parentID = currentFolderObj.id;
		if(!currentFolderObj.children) currentFolderObj.children=[];

		//--- put children into parent
		for (var i=0; i<rawFolders.length; i++){
			fold=rawFolders[i];
			if(fold.parentID==parentID){
				currentFolderObj.children.push(fold);
				currentFolderObj.leaf=false;
				if(recurs<this.folderLevelsExpanded+1) currentFolderObj.expanded=true;
				//if(parentID!=0) currentFolderObj.expanded=false;
			}
		}

		if (currentFolderObj.children && currentFolderObj.children.length>0){
			//--- loop through each child, and find their children
			for (i=0; i<currentFolderObj.children.length; i++){
				this.putFoldersIntoParent( rawFolders, currentFolderObj.children[i], recurs ); 
			}
		}
	},

	addBooksToFolderTree: function( rawBooks, folderNodes ) 
	{
		for(var i in rawBooks){
			var bk=rawBooks[i];
			if(!bk.name) continue;
			bk.type="book"
			var f = this.findFolder(bk.folderID);
			f = f ? f : vyew.od.folderNodes;
			f.children.push(bk);
		}
	},

	//sets data in grid, based on selected folder
	updateGrid: function( folderID )
	{	
		if(!folderID)folderID=0;
		this.bookStore.filter('folderID',folderID);
		if(this.folderTree && this.folderTree.getNodeById(folderID)){
			 this.folderTree.getNodeById(folderID).select();
			 this.folderTree.getNodeById(folderID).expand();
		}
	},








	/* ---------------------------------------------------- TREE ----------------------- */
	initTree: function()
	{
        var rootNode = new Ext.tree.AsyncTreeNode(vyew.od.folderNodes);
		//--- if there was already a root node, remove it...
		//var prevRootNode=this.folderTree.getNodeById(0)
		//if(prevRootNode) prevRootNode.remove();
		var frn=this.folderTree.getRootNode()
		for(var i=0; i<frn.childNodes.length; i++){ 
			if (frn.childNodes[i].remove) frn.childNodes[i].remove(); 
		}
		for(var i=0; i<vyew.od.folderNodes.children.length; i++){
			var n=new Ext.tree.AsyncTreeNode(vyew.od.folderNodes.children[i]);
			if(n) frn.appendChild(n);
		}
	},



	

	/**
	 * -------------------------------------------------------------------------
	 * 		GETTERS/SETTERS
	 * -------------------------------------------------------------------------
	 */
    getRootFrame: function() { return parent; },
    getMainFrame: function() { return parent.main; },
    getMainFlash: function() { 
		if(parent && parent.main && parent.main.getMainFlash)
			return parent.main.getMainFlash(); 
		else
			return false;
	},

    getFolderObjById: function(id){ return this.folderTree.getNodeById(id).attributes},
    getFolderNodeById: function(id){ return this.folderTree.getNodeById(id); },

    current_mid: 0,     	// current numeric Meeting ID (1234_5678)
    current_rmid: 0,     	// requested mid (could be customID, "tim_my document")

	/**
 	 * Parsses mid values for each type
	 * @return {object} - { mid  	full numeric meeting ID (12345_67890)
	 *						rmid 	requested meeting id (could be alpha-numeric, "tim/9878"
	 *						baseMID	eg. 12345
	 *						customID eg. "tim"
	 *						bid		numeric bookID (5678)
	 *						bookname eg. "mydocument"
	 */
	getMID: function() {
		var obj={};
		try {
			obj.mid=this.current_mid;
			obj.rmid=this.current_rmid;
			obj.baseMID=this.current_mid.match(/^[^_]*/)[0]
			obj.customID=this.current_rmid.match(/^[^_]*/)[0];
			if(!obj.customID) obj.customID=obj.baseMID;
			obj.bid=this.current_mid.match(/_(.*)/)[1];
			obj.bookname=this.current_rmid.match(/_(.*)/)[1];
			if(!obj.bookname) obj.bookname=obj.bid;
		} catch(e) {}
		return obj;
	},


	findFolder: function (id,folderNodes){
		var f,ff;
		if(!folderNodes) folderNodes=vyew.od.folderNodes;
		//id=parseInt(id);
		if(parseInt(folderNodes.id) == id) return folderNodes;
		if(folderNodes.children){
			for( var i in folderNodes.children ){
				f=folderNodes.children[i]
				ff = this.findFolder(id, f);
				if(ff && ff!=vyew.od.folderNodes) return ff;
			}
		}
	},


	test: 'test'
  };//end return func
}();//end of app




/**
 * Handles clicks from "powered by vyew" logo in upper right
 */
function poweredVyewClick(id)
{
	switch(id){
		case 1: 
		case 3:
			openRightFrame("pub.aboutvyew.html");
			break;
		case 2:
            openRightFrame("pub.aboutstanford.html");
            break;
	}
}


/**
 * -----------------------------------------------------------------
 *  Frame Utils
 * -----------------------------------------------------------------
 */

function openRightFrame(url)
{
	if(!url.match(/\//)){
		url="/"+top.vers+"/content/"+url;
	}
  try{
	var cols=top.$('#frameset2').attr("cols").split(",")
	cols[1]="0"; cols[2]="*";
	top.$('#frameset2').attr("cols",cols.join(','))
    if(url) top.$('frameset [name=rightframe]').attr('src',url);
  } catch(e){ throw new Error('VyewError3948: openRightFrame')}
}

function closeRightFrame()
{
  try{
    var cols=top.$('#frameset2').attr("cols").split(",")
    cols[1]="*"; cols[2]="0";
    top.$('#frameset2').attr("cols",cols.join(','))
  } catch(e){ throw new Error('VyewError3948b: closeRightFrame')}
}

function isRightFrameOpen()
{
	var cols=top.$('#frameset2').attr("cols").split(",")
	if(cols[2]=="*") return true;
	else return false;	
}

function getTimer(){
	return Math.floor(new Date().getTime()/1000);
}

function getFirebugConsole()
{
    try{
    //if top frame, use that console
    if(top!=window) var win=top;
    else win=this.window;
    if(typeof win.console == "undefined"){
        if(!win.loadFirebugConsole) return false;
        else win.loadFirebugConsole();
    }
    if(typeof win.console != "undefined" && win.console.debug) return win.console;
    return false;
    }catch(e){ return false; }
}

function dbg()
{
    var console=getFirebugConsole();
    if (!console) return;
    var out="";
    for(var i=0;i<arguments.length;i++){ out+=arguments[i]+", "; }
    out=out.substr(0,out.length-2);
    console.debug(out);
}

function dbd(x,txt)
{
    var console=getFirebugConsole();
    if(!console) return;
    if(txt) console.debug('---------------- '+txt);
    else console.debug('----------------');
    console.dir(x);
}




/******************************************************************************************
         publicbooks.FolderTree.js
 ******************************************************************************************/

/* ---------------------------------------------------- TREE ----------------------- 


*/

Ext.namespace('pb');
pb.FolderTree = new Ext.extend(Ext.tree.TreePanel, {
	initComponent: function() {
		Ext.apply(this, {
				id: 'folderTree',
			    region: 'center',
                margins: '2 0 0 0',
				animate: true, autoScroll: true,
				enableDD: false, border: false,
				containerScroll: true,
				border: false,
				rootVisible:false,
				dropConfig: {appendOnly: true},
				collapseFirst: false,
		        loader: new Ext.tree.TreeLoader({
					preloadChildren: true,
					clearOnLoad: false
				}),
				root: new Ext.tree.TreeNode({
					id:'invisible-root', text: 'Invisible Root',
					//singleClickExpand: false,
					expanded: true, 
					children: []
				})
			}); //end config obj

		/* ---------- Add Listeners ----------------- */
		this.addListener({
			click: function( node ){
				gMsg.fireEvent('treeEvent', {id:'selectfolder', node:node });
			},
			render:{
				fn: function(){ gMsg.fireEvent('treeEvent', {id:'onrender'}); },
				delay:2000
			}
        });

		new Ext.tree.TreeSorter(this, {folderSort:true});

		pb.FolderTree.superclass.initComponent.apply(this, arguments);
	},

	findNodeByFolderId: function( folderID, searchNode ) {
		if (!folderID) return false;
		if (!searchNode) searchNode = this.getRootNode();
		if (searchNode.attributes.ID = folderID) return searchNode;
		this.eachChild( function(node, folderID) {
			var n = this.findNodeByFolderId( folderID, node );
			if (n) return n;
		}.createDelegate(this, [folderID], 1));
		return false;

	}
});
Ext.reg('foldertree', pb.FolderTree);

//var n=myhome.app.folderTree.getNodeById('root').ui.getTextEl();

//te.startEdit(n)






/******************************************************************************************
         publicbooks.Vyewport.js
 ******************************************************************************************/

Ext.namespace('pb');

/**
 *  ---------------------------------------  MY VYEWBOOKS TAB - LAYOUT -----------------------------
 */
var vyewbooks_leftbar = {
	region: 'center',
	border: false,
	layout: 'border',
	collapsible: true,
	width: 200,
	renderTo: 'xmain',
	minSize: 175,
	maxSize: 350,
	/*defaults: {bodyStyle: 'background: url(img/bg-fade-white-grey.gif) repeat-y;'},*/
	margins: '2 0 2 2',
	cmargins: '2 2 2 2',
	bodyStyle:'padding:10px;',
	split: true,
	items: [
		{id:'toppanel', region:'north', height:0, border:false,
			bodyStyle: 'background: url(img/bg-fade-white-grey2.gif) repeat-y;'
		},
		{xtype: 'foldertree', bodyStyle: 'background-color: #F8F9E7;'},
		{id:'botpanel', region:'south', height:0, border:false,
			bodyStyle: 'background: url(img/bg-fade-white-grey2.gif) repeat-y;'
		}
	]
};

pb.Vyewport = Ext.extend(Ext.Viewport, {
    initComponent: function() {
        Ext.apply(this, vyewbooks_leftbar );
        pb.Vyewport.superclass.initComponent.apply(this, arguments);
    }
});

Ext.reg('vyewport', pb.Vyewport);



/******************************************************************************************
         swfaddress.js
 ******************************************************************************************/

/**
 * SWFAddress 2.1: Deep linking for Flash and Ajax - http://www.asual.com/swfaddress/
 *
 * SWFAddress is (c) 2006-2007 Rostislav Hristov and is released under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * This file has been modified by vyew in various places. Search for "vyew" to find where...
 */

if (typeof com == "undefined") var com = {};
if (typeof com.asual == "undefined") com.asual = {};
if (typeof com.asual.util == "undefined") com.asual.util = {};
   
/**
 * @class Utility class that provides detailed browser information.
 * @static
 * @ignore
 */
com.asual.util.Browser = new function() {

    var _version = -1;
    var _agent = navigator.userAgent;
    var _ie = false, _camino = false, _safari = false, _opera = false, 
        _firefox = false, _netscape = false, _mozilla = false;

    var _getVersion = function(s, i) {
        return parseFloat(_agent.substr(_agent.indexOf(s) + i));
    }
    
    if (_ie = /MSIE/.test(_agent))
        _version = _getVersion('MSIE', 4);
        
    if (_safari = /AppleWebKit/.test(_agent))
        _version = _getVersion('Safari', 7);
        
    if (_opera = /Opera/.test(_agent))
        _version = parseFloat(navigator.appVersion);
        
    if (_camino = /Camino/.test(_agent))
        _version = _getVersion('Camino', 7);
        
    if (_firefox = /Firefox/.test(_agent))
        _version = _getVersion('Firefox', 8);
        
    if (_netscape = /Netscape/.test(_agent))
        _version = _getVersion('Netscape', 9);
        
    if (_mozilla = /Mozilla/.test(_agent) && /rv:/.test(_agent))
        _version = _getVersion('rv:', 3);


    /**
     * Detects the version of the browser.
     * @return {Number}
     * @static
     */
    this.getVersion = function() {
        return _version;
    }

    /**
     * Detects if the browser is Internet Explorer.
     * @return {Boolean}
     * @static
     */
    this.isIE = function() {
        return _ie;
    }

    /**
     * Detects if the browser is Safari.
     * @return {Boolean}
     * @static
     */
    this.isSafari = function() {
        return _safari;
    }

    /**
     * Detects if the browser is Opera.
     * @return {Boolean}
     * @static
     */
    this.isOpera = function() {
        return _opera;
    }

    /**
     * Detects if the browser is Camino.
     * @return {Boolean}
     * @static
     */
    this.isCamino = function() {
        return _camino;
    }

    /**
     * Detects if the browser is Firefox.
     * @return {Boolean}
     * @static
     */
    this.isFirefox = function() {
        return _firefox;
    }

    /**
     * Detects if the browser is Netscape.
     * @return {Boolean}
     * @static
     */
    this.isNetscape = function() {
        return _netscape;
    }
        
    /**
     * Detects if the browser is Mozilla.
     * @return {Boolean}
     * @static
     */
    this.isMozilla = function() {
        return _mozilla;
    }
}

/**
 * @class Utility class that provides event helpers.
 * @static
 * @ignore
 */
com.asual.util.Events = new function() {

    var _cache = [];
    var _browser = com.asual.util.Browser;
    var _dcl = 'DOMContentLoaded';

    if (_browser.isIE() || _browser.isSafari()) {
        (function (){
            try {
                if (_browser.isIE() || !/loaded|complete/.test(document.readyState))
                    document.documentElement.doScroll('left');
            } catch(e) {
                return setTimeout(arguments.callee, 0);
            }
            for (var i = 0, e; e = _cache[i]; i++)
                if (e.t == _dcl) e.l.call(null);
        })();
    }

    /**
     * Adds an event listener to an object.
     * @param {Object} obj The object that provides events.
     * @param {String} type The type of the event.
     * @param {Function} listener The event listener function.
     * @return {void}
     * @static
     */
    this.addListener = function(obj, type, listener) {
        _cache.push({o: obj, t: type, l: listener});
        if (!(type == _dcl && (_browser.isIE() || _browser.isSafari()))) {
            if (obj.addEventListener)
                obj.addEventListener(type, listener, false);
            else if (obj.attachEvent)
                obj.attachEvent('on' + type, listener);
        }
    }

    /**
     * Removes an event listener from an object.
     * @param {Object} obj The object that provides events.
     * @param {String} type The type of the event.
     * @param {Function} listener The event listener function.
     * @return {void}     
     * @static
     */
    this.removeListener = function(obj, type, listener) {
        for (var i = 0, e; e = _cache[i]; i++) {
            if (e.o == obj && e.t == type && e.l == listener) {
                _cache.splice(i, 1);
                break;
            }
        }
        if (!(type == _dcl && (_browser.isIE() || _browser.isSafari()))) {
            if (obj.removeEventListener)
                obj.removeEventListener(type, listener, false);
            else if (obj.detachEvent)
                obj.detachEvent('on' + type, listener);
        }
    }

    var _unload = function() {
        for (var i = 0, evt; evt = _cache[i]; i++) {
            if (evt.t != _dcl)
                com.asual.util.Events.removeListener(evt.o, evt.t, evt.l);
        }
    }

    this.addListener(window, 'unload', _unload);
}

/**
 * Creates a new SWFAddress event.
 * @class Event class for SWFAddress.
 * @param {String} type Type of the event.
 */
SWFAddressEvent = function(type) {
    
    /**
     * String representation of this object.
     * @ignore
     */
    this.toString = function() {
        return '[object SWFAddressEvent]';
    }

    /**
     * The type of this event.
     * @type String
     */
    this.type = type;

    /**
     * The target of this event.
     * @type Function
     */
    this.target = [SWFAddress][0];

    /**
     * The value of this event.
     * @type String
     */
    this.value = SWFAddress.getValue();

    /**
     * The path of this event.
     * @type String
     */
    this.path = SWFAddress.getPath();
    
    /**
     * The folders in the deep linking path of this event.
     * @type Array
     */
    this.pathNames = SWFAddress.getPathNames();

    /**
     * The parameters of this event.
     * @type Object
     */
    this.parameters = {};

    var _parametersNames = SWFAddress.getParameterNames();
    for (var i = 0, l = _parametersNames.length; i < l; i++)
        this.parameters[_parametersNames[i]] = SWFAddress.getParameter(_parametersNames[i]);
    
    /**
     * The parameters names of this event.
     * @type Array     
     */
     this.parametersNames = _parametersNames;
}

/**
 * Init event.
 * @type String
 * @memberOf SWFAddressEvent
 * @static
 */
SWFAddressEvent.INIT = 'init';

/**
 * Change event.
 * @type String
 * @memberOf SWFAddressEvent
 * @static 
 */
SWFAddressEvent.CHANGE = 'change';

/**
 * @class The SWFAddress class can be configured with query parameters using the following format:
 * swfaddress.js?html=false&history=1&tracker=pageTracker._trackPageview&strict=1.<br /> 
 * The list of supported options include:<br /><br />
 * <code>history:Boolean</code> - Enables or disables the creation of history entries.<br />
 * <code>html:Boolean</code> - Enables or disables the usage of swfaddress.html.<br />
 * <code>strict:Boolean</code> - Enables or disables the strict mode.<br />
 * <code>tracker:String</code> - Sets a function for page view tracking.<br />
 * @static 
 */ 
SWFAddress = new function() {

    var _browser = com.asual.util.Browser;
    var _events = com.asual.util.Events;
    var _version = _browser.getVersion();
    var _supported = false;

    if (_browser.isIE()) 
        _supported = _version >= 6;
        
    if (_browser.isSafari())
        _supported = _version >= 312;
        
    if (_browser.isOpera())
        _supported = _version >= 9.02;
        
    if (_browser.isCamino()) 
        _supported = _version >= 1;
        
    if (_browser.isFirefox())
        _supported = _version >= 1;
        
    if (_browser.isNetscape())
        _supported = _version >= 8;
        
    if (_browser.isMozilla())
        _supported = _version >= 1.8;
	
	//--- Added by vyew - try/catch statement
	//--- this was breaking iframe load accross domains
	try {
		var __test=top.document.title
    	var _t = top;
	}catch(e){ 
		var _t=window; 
	}
    var _d = _t.document;
    var _h = _t.history;
    var _l = _t.location;
    var _st = setTimeout;
    
    var FUNCTION = 'function';
    var UNDEFINED = 'undefined';
    var SWFADDRESS = 'swfaddress';

    var _iframe, _form, _url;
    var _title = _d.title;
    var _length = _h.length;
    var _silent = false;
    var _listeners = {};
    var _stack = [];
    var _ids = [];
    
    var _opts = {};
    _opts.history = true;
    _opts.html = false;
    _opts.strict = true;
    _opts.tracker = '_trackDefault';
    
    /*// commented out by vyew
      if ((!_supported && _l.href.indexOf('#') != -1) || 
        (_browser.isSafari() && _version < 412 && _l.href.indexOf('#') != -1 && _l.search != '')){
        _d.open();
        _d.write('<html><head><meta http-equiv="refresh" content="0;url=' + 
            _l.href.substr(0, _l.href.indexOf('#')) + '" /></head></html>');
        _d.close();
    }*/

    var _getHash = function() {
        var index = _l.href.indexOf('#');
        if (index != -1) {
            var hash = unescape(_l.href.substr(index + 1));
// 3 lines commented by vyew
//            if (/^[a-z0-9 ,=_&\-\.\?\+\/]*$/i.test(hash))
                return hash;
//            else
//                _l.replace(_l.href.substr(0, index));
        }
        return '';
    }

    var _value = _getHash();

    var _strictCheck = function(value, force) {
        if (_opts.strict)
            value = force ? (value.substr(0, 1) != '/' ? '/' + value : value) : (value == '' ? '/' : value);
        return value;
    }

    var _ieLocal = function(value) {
        return (_browser.isIE() && _l.protocol == 'file:') ? _value.replace(/\?/, '%3F') : value;    
    }

    var _searchScript = function(el) {
        if (el.src && /swfaddress\.js(\?.*)?$/.test(el.src)) return el;
        for (var i = 0, l = el.childNodes.length, s; i < l; i++)
            if (s = _searchScript(el.childNodes[i])) return s;
    }
    
    var _titleCheck = function() {
        if (_browser.isIE() && _d.title != _title)
            SWFAddress.setTitle(_title);
    }

    var _listen = function() {
        if (!_silent) {
            var hash = _getHash();
            if (_browser.isIE()) {
                if (_value != hash) {
					//alert("_listen: \nold:"+_value+"\nnew:"+hash);
                    if (_version < 7)
                        _l.reload();
                    else
                        SWFAddress.setValue(hash);
                }
            } else if (_browser.isSafari() && _version < 523) {
                if (_length != _h.length) {
                    _length = _h.length;
                    if (typeof _stack[_length - 1] != UNDEFINED)
                        _value = _stack[_length - 1];
                    _update();
                }
            } else if (_value != hash) {
				//alert("_listen: \nold:"+_value+"\nnew:"+hash);
                _value = hash;
                _update();
            }
            _titleCheck();
        }
    }

    var _jsDispatch = function(type) {
        if (SWFAddress.hasEventListener(type))
            SWFAddress.dispatchEvent(new SWFAddressEvent(type));
        type = type.substr(0, 1).toUpperCase() + type.substr(1);
        if(typeof SWFAddress['on' + type] == FUNCTION)
            SWFAddress['on' + type]();
    }

    var _jsInit = function() {
        _jsDispatch('init');
    }

    var _jsChange = function() {
        _jsDispatch('change');
    }

    var _swfChange = function() {
		//alert("swfChange: "+SWFAddress.getValue());
        for (var i = 0, id, value = SWFAddress.getValue(), setter = 'setSWFAddressValue'; id = _ids[i]; i++) {
            var obj = document.getElementById(id);
            if (obj) {
                if (obj.parentNode && typeof obj.parentNode.so != UNDEFINED) {
                    obj.parentNode.so.call(setter, value);
                } else {
                    if (!(obj && typeof obj[setter] != UNDEFINED)) {
                        var objects = obj.getElementsByTagName('object');
                        var embeds = obj.getElementsByTagName('embed');
                        obj = ((objects[0] && typeof objects[0][setter] != UNDEFINED) ? 
                            objects : ((embeds[0] && typeof embeds[0][setter] != UNDEFINED) ? 
                                embeds[0] : null));
                    }
                    if (obj)
                        obj[setter](value);
                } 
            } else if (obj = document[id]) {
                if (typeof obj[setter] != UNDEFINED)
                    obj[setter](value);
            }
        }
    }

    var _update = function() {
//this only works with firebug
//console.debug('_update func called');
        _swfChange();
        _jsChange();
        _st(_track, 10);
    }

    var _trackDefault = function(value) {
        if (typeof urchinTracker == FUNCTION) 
            urchinTracker(value);
        if (typeof pageTracker != UNDEFINED && typeof pageTracker._trackPageview == FUNCTION)
            pageTracker._trackPageview(value);
    }
    
    eval('var _trackDefault = ' + _trackDefault + ';');
    
    var _track = function() {
        if (typeof _opts.tracker != UNDEFINED && eval('typeof ' + _opts.tracker + ' != "' + UNDEFINED + '"')) {
            var fn = eval(_opts.tracker);
            if (typeof fn == FUNCTION)
                fn((_l.pathname + (/\/$/.test(_l.pathname) ? '' : '/') + SWFAddress.getValue()).replace(/\/\//, '/').replace(/^\/$/, ''));
        }
    }
    
    var _htmlWrite = function() {
        var doc = _iframe.contentWindow.document;
        doc.open();
        doc.write('<script>var ' + SWFADDRESS + ' = "' + _getHash() + '";</script>');
        doc.close();
    }

    var _htmlLoad = function() {
        var win = _iframe.contentWindow;
        if (_opts.html) {
            var src = win.location.href;
            _value = (src.indexOf('?') > -1) ? src.substr(src.indexOf('?') + 1) : '';
        } else {
            _value = (typeof win[SWFADDRESS] != UNDEFINED) ? win[SWFADDRESS] : '';
        }
        win.document.title = _d.title;
        if (_value != _getHash()) {
            _update();
            _l.hash = _ieLocal(_value);
        }
    }

    var _load = function() {
//only works with firebug
//console.debug('_load func called');
        var attr = 'id="' + SWFADDRESS + '" style="position:absolute;top:-9999px;"';
        if (_browser.isIE()) {
            document.body.appendChild(document.createElement('div')).innerHTML = '<iframe ' + attr + ' src="' + 
                (_opts.html ? _url.replace(/\.js(\?.*)?$/, '.html') + '?' + _getHash() : 'javascript:false;') + 
                '" width="0" height="0"></iframe>';
            _iframe = document.getElementById(SWFADDRESS);
            _st(function() {
                _events.addListener(_iframe, 'load', _htmlLoad);            
                if (!_opts.html && typeof _iframe.contentWindow[SWFADDRESS] == UNDEFINED) 
                    _htmlWrite();
            }, 10);
        } else if (_browser.isSafari()) {
            if (_version < 412) {
                document.body.innerHTML += '<form ' + attr + ' method="get"></form>';
                _form = document.getElementById(SWFADDRESS);
            }
            if (typeof _l[SWFADDRESS] == UNDEFINED) _l[SWFADDRESS] = {};
            if (typeof _l[SWFADDRESS][_l.pathname] != UNDEFINED) _stack = _l[SWFADDRESS][_l.pathname].split(',');
        } else if (_browser.isOpera() && _ids.length == 0 && typeof navigator.plugins['Shockwave Flash'] == 'object') {
            document.body.innerHTML += '<embed ' + attr + ' src="' + _url.replace(/\.js(\?.*)?$/, '.swf') + 
                '" type="application/x-shockwave-flash" />';
        }
        _st(_jsInit, 1);
        _st(_jsChange, 2);
        _st(_track, 10);
        setInterval(_listen, 1000);
    }

    /**
     * Init event.
     * @type Function
     * @event
     * @static
     */
    this.onInit = null;
    
    /**
     * Change event.
     * @type Function
     * @event
     * @static
     */
    this.onChange = null;
    
    /**
     * String representation of this class.
     * @ignore
     */
    this.toString = function() {
        return '[class SWFAddress]';
    }

    /**
     * Loads the previous URL in the history list.
     * @return {void}
     * @static
     */
    this.back = function() {
        _h.back();
    }

    /**
     * Loads the next URL in the history list.
     * @return {void}
     * @static
     */
    this.forward = function() {
        _h.forward();
    }

    /**
     * Loads a URL from the history list.
     * @param {Number} delta An integer representing a relative position in the history list.
     * @return {void}
     * @static
     */
    this.go = function(delta) {
        _h.go(delta);
    }

    /**
     * Opens a new URL in the browser. 
     * @param {String} url The resource to be opened.
     * @param {String} target Target window.
     * @return {void}
     * @static
     */
    this.href = function(url, target) {
        target = (typeof target != UNDEFINED) ? target : '_self';     
        if (target == '_self')
            self.location.href = url; 
        if (target == '_top')
            _l.href = url; 
        if (target == '_blank')
            window.open(url); 
        else
            _t.frames[target].location.href = url; 
    }

    /**
     * Opens a browser popup window. 
     * @param {String} url Resource location.
     * @param {String} name Name of the popup window.
     * @param {String} options Options which get evaluted and passed to the window.open() method.
     * @param {String} handler Optional JavaScript code for popup handling.    
     * @return {void}
     * @static
     */
    this.popup = function(url, name, options, handler) {
        var popup = window.open(url, name, eval(options));
        eval(handler);
    }

    /**
     * Registers an event listener.
     * @param {String} type Event type.
     * @param {Function} listener Event listener.
     * @return {void}
     * @static
     */
    this.addEventListener = function(type, listener) {
        if (typeof _listeners[type] == UNDEFINED)
            _listeners[type] = [];
        _listeners[type].push(listener);
    }

    /**
     * Removes an event listener.
     * @param {String} type Event type.
     * @param {Function} listener Event listener.
     * @return {void}
     * @static     
     */
    this.removeEventListener = function(type, listener) {
        if (typeof _listeners[type] != UNDEFINED) {
            for (var i = 0, l; l = _listeners[type][i]; i++)
                if (l == listener) break;
            _listeners[type].splice(i, 1);
        }
    }

    /**
     * Dispatches an event to all the registered listeners. 
     * @param {Object} event Event object.
     * @return {Boolean}
     * @static
     */
    this.dispatchEvent = function(event) {
        if (typeof _listeners[event.type] != UNDEFINED && _listeners[event.type].length) {
            event.target = this;
            for (var i = 0, l; l = _listeners[event.type][i]; i++)
                l(event);
            return true;           
        }
        return false;
    }

    /**
     * Checks the existance of any listeners registered for a specific type of event. 
     * @param {String} event Event type.
     * @return {Boolean}
     * @static
     */
    this.hasEventListener = function(type) {
        return (typeof _listeners[type] != UNDEFINED && _listeners[type].length > 0);
    }
    
    /**
     * Provides the base address of the document. 
     * @return {String}
     * @static
     */
    this.getBaseURL = function() {
        var url = _l.href;
        if (url.indexOf('#') != -1)
            url = url.substr(0, url.indexOf('#'));
        if (url.substr(url.length - 1) == '/')
            url = url.substr(0, url.length - 1);
        return url;
    }

    /**
     * Provides the state of the strict mode setting. 
     * @return {Boolean}
     * @static
     */
    this.getStrict = function() {
        return _opts.strict;
    }

    /**
     * Enables or disables the strict mode.
     * @param {Boolean} strict Strict mode state.
     * @return {void}
     * @static
     */
    this.setStrict = function(strict) {
        _opts.strict = strict;
    }

    /**
     * Provides the state of the history setting. 
     * @return {Boolean}
     * @static
     */
    this.getHistory = function() {
        return _opts.history;
    }

    /**
     * Enables or disables the creation of history entries.
     * @param {Boolean} history History state.
     * @return {void}
     * @static
     */
    this.setHistory = function(history) {
        _opts.history = history;
    }

    /**
     * Provides the tracker function.
     * @return {String}
     * @static
     */
    this.getTracker = function() {
        return _opts.tracker;
    }

    /**
     * Sets a function for page view tracking. The default value is 'urchinTracker'.
     * @param {String} tracker Tracker function.
     * @return {void}
     * @static
     */
    this.setTracker = function(tracker) {
        _opts.tracker = tracker;
    }

    /**
     * Provides a list of all the Flash objects registered. 
     * @return {Array}
     * @static
     */
    this.getIds = function() {
        return _ids;
    }

    /**
     * Provides the id the first and probably the only Flash object registered. 
     * @return {String}
     * @static
     */
    this.getId = function(index) {
        return _ids[0];
    }

    /**
     * Sets the id of a single Flash object which will be registered for deep linking.
     * @param {String} id ID of the object.
     * @return {void}
     * @static
     */
    this.setId = function(id) {
        _ids[0] = id;
    }

    /**
     * Adds an id to the list of Flash object registered for deep linking.
     * @param {String} id ID of the object.
     * @return {void}
     * @static
     */
    this.addId = function(id) {
        this.removeId(id);
        _ids.push(id);
    }

    /**
     * Removes an id from the list of Flash object registered for deep linking.
     * @param {String} id ID of the object.
     * @return {void}
     * @static
     */
    this.removeId = function(id) {
        for (var i = 0; i < _ids.length; i++) {
            if (id == _ids[i]) {
                _ids.splice(i, 1);
                break;
            }
        }
    }

    /**
     * Provides the title of the HTML document.
     * @return {String}
     * @static
     */
    this.getTitle = function() {
        return _d.title;
    }

    /**
     * Sets the title of the HTML document.
     * @param {String} title Title value.
     * @return {void}
     * @static
     */
    this.setTitle = function(title) {
        if (!_supported) return null;
        if (typeof title == UNDEFINED) return;
        if (title == 'null') title = '';
        _title = _d.title = title;
        _st(function() {
            if (_iframe && _iframe.contentWindow && _iframe.contentWindow.document && _iframe.contentWindow.title)
                _iframe.contentWindow.document.title = _title;
         }, 1000);
    }

    /**
     * Provides the status of the browser window.
     * @return {String}
     * @static
     */
    this.getStatus = function() {
        return _t.status;
    }

    /**
     * Sets the status of the browser window.
     * @param {String} status Status value.
     * @return {void}
     * @static
     */
    this.setStatus = function(status) {
        if (!_supported) return null;
        if (typeof status == UNDEFINED) return;
        if (!_browser.isSafari()) {
            status = _strictCheck((status != 'null') ? status : '', true);
            if (status == '/') status = '';
            if (!(/http(s)?:\/\//.test(status))) {
                var index = _l.href.indexOf('#');
                status = (index == -1 ? _l.href : _l.href.substr(0, index)) + '#' + status;
            }
            _t.status = status;
        }
    }

    /**
     * Resets the status of the browser window.
     * @return {void}
     * @static
     */
    this.resetStatus = function() {
        _t.status = '';
    }

    /**
     * Provides the current deep linking value.
     * @return {String}
     * @static
     */
    this.getValue = function() {
        if (!_supported) return null;
        return _strictCheck(_value, false);
    }

    /**
     * Sets the current deep linking value.
     * @param {String} value A value which will be appended to the base link of the HTML document.
     * @return {void}
     * @static
     */
    this.setValue = function(value) {
        if (!_supported) return null;
        if (typeof value == UNDEFINED) return;
		//vyew add:
		if(value.match(/\/undefined\//)){
			try{
				dbg("CAUGHT UNDEFINED ERROR:"+value);
			}catch(e){}
			return;
		}
        if (value == 'null') value = ''
        value = _strictCheck(value, true);
        if (value == '/') value = '';
        if (_value == value) return;
		//alert("setValue: "+value);
        _value = value;
        _silent = true;
        _update();
        _stack[_h.length] = _value;
        if (_browser.isSafari()) {
            if (_opts.history) {
                _l[SWFADDRESS][_l.pathname] = _stack.toString();
                _length = _h.length + 1;
                if (_version < 412) {
                    if (_l.search == '') {
                        _form.action = '#' + _value;
                        _form.submit();
                    }
                } else if (_version < 523){
                    var evt = document.createEvent('MouseEvents');
                    evt.initEvent('click', true, true);
                    var anchor = document.createElement('a');
                    anchor.href = '#' + _value;
                    anchor.dispatchEvent(evt);                
                } else {
                    _l.hash = '#' + _value;
                }
            } else {
                _l.replace('#' + _value);
            }
        } else if (_value != _getHash()) {
            if (_opts.history)
                _l.hash = '#' + _ieLocal(_value);
            else
                _l.replace('#' + _value);
        }
        if (_browser.isIE() && _opts.history) {
            if (_opts.html) {
                var loc = _iframe.contentWindow.location;
                loc.assign(loc.pathname + '?' + _getHash());
            } else {
                _htmlWrite();
            }
        }
        if (_browser.isSafari())
            _st(function(){ _silent = false; }, 1);
        else
            _silent = false;
    }

    /**
     * Provides the deep linking value without the query string.
     * @return {String}
     * @static
     */
    this.getPath = function() {
        var value = this.getValue();
        return (value.indexOf('?') != -1) ? value.split('?')[0] : value;
    }

    /**
     * Provides a list of all the folders in the deep linking path.
     * @return {Array}
     * @static
     */
    this.getPathNames = function() {
        var path = SWFAddress.getPath();
        var names = path.split('/');
        if (path.substr(0, 1) == '/')
            names.splice(0, 1);
        if (path.substr(path.length - 1, 1) == '/')
            names.splice(names.length - 1, 1);
        return names;
    }

    /**
     * Provides the query string part of the deep linking value.
     * @return {String}
     * @static
     */
    this.getQueryString = function() {
        var value = this.getValue();
        var index = value.indexOf('?');
        return (index != -1 && index < value.length) ? value.substr(index + 1) : '';
    }

    /**
     * Provides the value of a specific query parameter.
     * @param {String} param Parameter name.
     * @return {String}
     * @static
     */
    this.getParameter = function(param) {
        var value = this.getValue();
        var index = value.indexOf('?');
        if (index != -1) {
            value = value.substr(index + 1);
            var params = value.split('&');
            var p, i = params.length;
            while(i--) {
                p = params[i].split('=');
                if (p[0] == param)
                    return p[1];
            }
        }
        return '';
    }

    /**
     * Provides a list of all the query parameter names.
     * @return {Array}
     * @static
     */
    this.getParameterNames = function() {
        var value = this.getValue();
        var index = value.indexOf('?');
        var names = [];
        if (index != -1) {
            value = value.substr(index + 1);
            if (value != '' && value.indexOf('=') != -1) {
                var params = value.split('&');
                var i = 0;
                while(i < params.length) {
                    names.push(params[i].split('=')[0]);
                    i++;
                }
            }
        }
        return names;
    }

    if (_supported) {
    
        for (var i = 1; i < _length; i++)
            _stack.push('');
            
        _stack.push(_getHash());
    
        if (_browser.isIE() && _l.hash != _getHash())
            _l.hash = '#' + _ieLocal(_getHash());
    
        try {
            _url = String(_searchScript(document).src);
            var qi = _url.indexOf('?');
            if (_url && qi > -1) {
                var param, params = _url.substr(qi + 1).split('&');
                for (var i = 0, p; p = params[i]; i++) {
                    param = p.split('=');
                    if (/^(history|html|strict)$/.test(param[0]))
                        _opts[param[0]] = (isNaN(param[1]) ? eval(param[1]) : (parseFloat(param[1]) > 0));
                    if (/^tracker$/.test(param[0]))
                        _opts[param[0]] = param[1];
                }
            }
        } catch(e) {}
        if (/file:\/\//.test(_l.href)) _opts.html = false;
    
        _titleCheck();
        _events.addListener(document, 'DOMContentLoaded', _load);
    
    } else {
        _track();
    }
}

/**
 * SWFAddress embed hooks.
 * @ignore
 */
new function() {

    var _func, _args;
    var UNDEFINED = 'undefined';

    if (typeof swfobject != UNDEFINED) SWFObject = swfobject;
    if (typeof FlashObject != UNDEFINED) SWFObject = FlashObject;
    
    if (typeof SWFObject != UNDEFINED) {
        if (SWFObject.prototype && SWFObject.prototype.write) {
            _func = SWFObject.prototype.write;
            SWFObject.prototype.write = function() {
                _args = arguments;
                if (this.getAttribute('version').major < 8) {
                    this.addVariable('$swfaddress', SWFAddress.getValue());
                    ((typeof _args[0] == 'string') ? 
                        document.getElementById(_args[0]) : _args[0]).so = this;
                }
                var success;
                if (success = _func.apply(this, _args))
                    SWFAddress.addId(this.getAttribute('id'));
                return success;
            }
        } else {
            _func = SWFObject.registerObject;
            SWFObject.registerObject = function() {
                _args = arguments;
                _func.apply(this, _args);
                SWFAddress.addId(_args[0]);            
            }
            _func = SWFObject.createSWF;
            SWFObject.createSWF = function() {
                _args = arguments;
                _func.apply(this, _args);
                SWFAddress.addId(_args[0].id);            
            }
            _func = SWFObject.embedSWF;
            SWFObject.embedSWF = function() {
                _args = arguments;
                _func.apply(this, _args);
                SWFAddress.addId(_args[8].id);            
            }
        }
    }
    
    if (typeof UFO != UNDEFINED) {
        _func = UFO.create;
        UFO.create = function() {
            _args = arguments;
            _func.apply(this, _args);
            SWFAddress.addId(_args[0].id);        
        }
    }
    
    if (typeof AC_FL_RunContent != UNDEFINED) {
        _func = AC_FL_RunContent;
        AC_FL_RunContent = function() {
            _args = arguments;        
            _func.apply(this, _args);
            for (var i = 0, l = _args.length; i < l; i++)
                if (_args[i]== 'id') SWFAddress.addId(_args[i+1]);
        }
    }
}


