/*
By - Santoshkumar Bhot
Last updated - November 30 2006
Copyright - Pramati Technologies.

All hail the FSM and Its noodly greatness.

Script to have an ajax style FolderChooser. Called with -
new Locationchooser(target)
where target - id of the input field where the result of the folder chooser is to be placed.
That's all! Mess around with the css, etc to customize look and feel of the folder chooser.
DON'T change the class names or their inheritance. You could but things would break, and nobody wants that :P.
*/

// define constants
// IE does not support the js 'const' keyword

var currentlyActiveTagCloudStyle = 0;

var SORT_NAME 		= 'sort_name';
var SORT_FREQ 		= 'sort_freq';
var SORT_DATE 		= 'sort_date';
var SORT_DEFAULT 	= SORT_NAME;
var ORDER_ASC 		= 'order_asc';
var ORDER_REVERSE 	= 'order_reverse';
var VIEW_CLOUD 		= 'view_cloud';
var VIEW_LIST 		= 'view_list';
var MODE_EDIT 		= 'edit';
var MODE_SELECT		= 'select';
var MODE_VIEW		= 'view';
var USG_WEEK		= 'last week';
var USG_24HOURS		= 'last 24 hours';
var USG_MONTH		= 'last month';
var USG_ALL			= 'all time';

var roTagCloudDataSource = Class.create();

Object.extend(roTagCloudDataSource.prototype,{
		initialize:function(){
			this.tags = new Array();
		},

		getTags:function(){

		},

		getTagByName: function(tagName){

		},

		getUrl:function(tagName){
			return this.tags.find(function(member, index){
				return member.tagName == tagName;
			}).url;
		}
});

var wTagCloudDataSource = Class.create();

Object.extend(wTagCloudDataSource.prototype,Object.extend(roTagCloudDataSource.prototype,{
		initialize:function(){},

		addTags:function(){
		},

		renameTag:function(){

		},

		mergeTags:function(){

		},

		deleteTags:function(){

		}
}));

var oTagCloud = Class.create();

oTagCloud.prototype = {
		initialize:function(id,targetDivId,ds){
			this.options = Object.extend({
				cloudtitle:			null,
				mode:				MODE_VIEW,			// One of MODE_EDIT, MODE_if(tagCloud.isNotDuplicate(elt.value,tagText)){SELECT, MODE_VIEW,
				minimalMode:		'off',				// Show/hide toolbar and advanced controls
				rankOn:			    false, 				// display frequency in cloud?
				colorsOn:			true, 				// display colors in cloud?
				textSizeOn:			true, 				// display text sizes in cloud?
				tagView:			VIEW_CLOUD,  		// 'view_list' or 'view_cloud'
				contentdiv: 		'cloudContent', 	// ID of div holding the actual tags HTML
				sortOrder:			ORDER_ASC, 			// order of the tags list: ORDER_ASC or ORDER_REVERSE
				tagSeparator:		', ',			// inserted between tags, &#x85; = elipsis
				sortField:			SORT_DEFAULT, 		// SORT_DEFAULT, SORT_FREQ, SORT_DATE, SORT_NAME
				tagsLimit: 			'All',				// limits how many tags are displayed
														// 'All' displays all available tags
				dioId:              "",                 // Digital Object ID
				urlBase:            "",
				currusagefilter: 	USG_ALL,		    // filters the tags based on recency of usage
														// options are USG_MONTH, USG_WEEK, USG_24HOURS, USG_ALL
				// the following are ignored if minimalMode is 'on'
				moreOptions:        'on',              // advanced options drawer available?
				sorterOn:           true,              // show/hide Sort control
				styleSwitcherOn:    true,              // show/hide Style control
				usageFilterOn:      true,              // show/hide Usage filter control
				tagLimiterOn:       true,               // show/hide taglimiter control
				noOfStyles:         6,
				currentShowSort:    "Most used",
				dialogWin:         false,
				returnTxtFieldId:   '',
				tagCloudHeight:     null,
                activeStyleSheet:   0,
                tagLinkWindow:'_self'    
            },arguments[3] || {});
            this.setActiveStyleSheet(this.options.activeStyleSheet);
            if(this.options.dialogWin)
                this.options.contentdiv = 'dialog_' + this.options.contentdiv;

            //constructor initialization
            this.firstTimeInvocation=true;
            this.filterClick = 0;
			this.id = id;
			this.aTag = 'aTag_' + ((this.options.dialogWin) ? 'tray' : 'page');
			this.editFieldId = (this.options.mode == MODE_SELECT) ? 'editFieldSelect' : 'editField';
			this.targetdiv = targetDivId;
			this.datasource = ds;       //datasource is a global variable declared in jsp
												//just before initializing tab cloud object instance
			this.editedTags = false;	//flag to check if tags were edited after the tagcloud has been opened
			this.viewTags = new Array();

			// Internal Attributes
			// define mode, options
			this.editorOpen = (this.options.dialogWin && this.options.mode == 'edit'); 	// this adds an onclick handler to all tag hyperlinks
			this.optionsOpen = false;

			// toggle between these predefined tag limits
			this.limitsList = [25, 50, 100, "All"];
			// toggle between these predefined usage filters
			this.usageList = [USG_MONTH, USG_WEEK, USG_24HOURS, USG_ALL];
			this.sortToShowList = ["Most used", "Least used", "Latest", "Oldest"];

			this.currStyleSheet = 0;

			var cloudContentHeight = 0;
			if(this.options.dialogWin && (this.options.mode == MODE_EDIT)){
				cloudContentHeight = 190;
			}else if(this.options.dialogWin && (this.options.mode == MODE_VIEW)){
                cloudContentHeight = 200;
			}else if(this.options.dialogWin && (this.options.mode == MODE_SELECT)){
				cloudContentHeight = 175;
			}

			var arrContent = new Array();
			if(this.options.dialogWin)
				arrContent[arrContent.length] = '<div id="trayTagCloudContainer" class="leftSideContainerTagsPage">';
			else
				arrContent[arrContent.length] = '<div class="leftSideContainerTagsPage">';

			if (this.options.cloudtitle != null) {
				arrContent[arrContent.length] = '<div class="tagContainerTitle">';
				arrContent[arrContent.length] = this.options.cloudtitle;
				arrContent[arrContent.length] = '</div>';
			}
			var colorsChecked = (this.options.colorsOn) ? ' checked ' : '';
			var textSizeChecked = (this.options.textSizeOn) ? ' checked ' : '';
			var freqChecked = (this.options.rankOn) ? ' checked ' : '';

			if (!this.isMinimalMode()) {
				arrContent[arrContent.length] = '<div id="cloudControls">';
				arrContent[arrContent.length] =     '<ul class="tagCloudControlList">';

				if(this.options.usageFilterOn)
					arrContent[arrContent.length] =     '<li id="usagefilter">Used <a href="javascript:void(0);" onclick="' + this.id + '.toggleUsageFilter(); return false;" title="last month | last week | last 24 hours | all time"><span id="ulabel">' + this.options.currusagefilter + '</span></a></li>';

				if(this.options.tagLimiterOn)
					arrContent[arrContent.length] =     '<li id="taglimiter">Showing <a href="javascript:void(0);" onclick="' + this.id + '.toggleTagLimit(); return false;" title="25 | 50 | 100 | All"><span id="limitlabel">' + this.options.tagsLimit + '</span></a> tags</li>';

				if(this.options.tagLimiterOn)
					arrContent[arrContent.length] =     '<li id="showSortOrder">Showing <a href="javascript:void(0);" onclick="' + this.id + '.toggleShowSorting(); return false;" title="Most used | Least used | Latest | Oldest"><span id="sortShowing">' + this.options.currentShowSort + '</span></a></li>';

				if(this.options.sorterOn)
					arrContent[arrContent.length] =     '<li id="sorter">Sort: <a href="javascript:void(0);" onclick="' + this.id + '.toggleSorting(SORT_NAME); return false;" title="A-z | Z-a"><span id="alphalabel">A-z</span></a></li>';

				if(this.options.styleSwitcherOn)
					arrContent[arrContent.length] =     '<li id="styleswitcher">Style <a href="javascript:void(0);" onclick="' + this.id + '.setNextStyleSheet(); return false;" title="Apply next style">Next</a></li>';

				if(this.options.moreOptions.toLowerCase() == 'on')
					arrContent[arrContent.length] =     '<li id="showmore" class="end"><a href="javascript:void(0);" onclick="' + this.id + '.toggleMoreOptions(); return false;" title="Open the options drawer"><span id="showmorelabel">More options &raquo;</span></a></li>';

				arrContent[arrContent.length] =     '</ul>';
				arrContent[arrContent.length] =     '<div id="moreOptions" style="display: none">';
				arrContent[arrContent.length] =      '<ul class="tagCloudControlList">';
				arrContent[arrContent.length] =          '<li id="colors"><input type="checkbox"' + colorsChecked + 'id="colchk" onclick="' + this.id + '.toggleColors();" />&nbsp;<label for="colchk">Colors</label></li>';
				arrContent[arrContent.length] =          '<li id="txtsize"><input type="checkbox"' + textSizeChecked + 'id="txtchk" onclick="' + this.id + '.toggleTextSize();" />&nbsp;<label for="txtchk">Text size</label></li>';
				arrContent[arrContent.length] =          '<li id="freqview"><input type="checkbox" id="freqchk"' + freqChecked + 'onclick="' + this.id + '.toggleFrequency();" />&nbsp;<label for="freqchk">Show Frequency</label></li>';
				arrContent[arrContent.length] =          '<li id="viewer" class="end">View: <a href="javascript:void(0);" onclick="' + this.id + '.viewAsCloud(); return false;">cloud</a> | <a href="javascript:void(0);" onclick="' + this.id + '.viewAsList(); return false;">list</a></li>';
				arrContent[arrContent.length] =      '</ul>';
				arrContent[arrContent.length] =     '</div>';
				arrContent[arrContent.length] = '</div>';
			}

			if(this.options.minimalMode == 'off'){
				if(this.options.dialogWin){
					arrContent[arrContent.length] = '<div id="' + this.options.contentdiv + '_holder" compressed="false" class="trayTagContent" style="height:' + (cloudContentHeight + 1) + 'px;overflow:auto;border:1px solid #444;">';
					arrContent[arrContent.length] =     '<div id="' + this.options.contentdiv + '" class="tagContent"></div>';
					arrContent[arrContent.length] = '</div>';
				}else{
					if(this.options.tagCloudHeight!=null)
						arrContent[arrContent.length] =     '<div id="' + this.options.contentdiv + '" class="tagContent" style="height:'+this.options.tagCloudHeight+'px;overflow:auto;overflow-y:auto;overflow-x:hidden;"></div></div>';
					else
						arrContent[arrContent.length] =     '<div id="' + this.options.contentdiv + '" class="tagContent"></div></div>';
				}
			}else{
				if(this.options.tagCloudHeight!=null)
					arrContent[arrContent.length] =     '<div id="' + this.options.contentdiv + '" class="tagContent" style="height:'+this.options.tagCloudHeight+'px;overflow-y:auto;overflow-x:hidden;"></div></div>';
				else
					arrContent[arrContent.length] =     '<div id="' + this.options.contentdiv + '" class="tagContent"></div></div>';
			}

			var editorDisplayStyle = 'none';

			if(this.options.mode.toLowerCase() == MODE_EDIT){
				arrContent[arrContent.length] = '<div id="editor" style="background-color:#000;display:'+ editorDisplayStyle +'; border: 0px;"><table width="100%" border="0"><tbody><tr><td style="width:50px;">Editing: </td>';
				arrContent[arrContent.length] = '<td><input type="text" id="'+ this.editFieldId +'"class="editme" maxlength="255" value="" /></td></tr></tbody></table>';
				arrContent[arrContent.length] =      '<div id="actions">';
				arrContent[arrContent.length] =          '<a class="actionLink" href="javascript:void(0);" onclick="' + this.id + '.editTags(\'add\'); return false;" title="Enter new tag above to add">Add</a> | ';
				arrContent[arrContent.length] =          '<a class="actionLink" href="javascript:void(0);" onclick="' + this.id + '.editTags(\'delete\'); return false;" title="Select tag(s) from tagcloud to delete">Delete</a> | ';
				arrContent[arrContent.length] =          '<a class="actionLink" href="javascript:void(0);" onclick="' + this.id + '.editTags(\'rename\'); return false;" title="Select tag from tagcloud to rename">Rename</a> | ';
				arrContent[arrContent.length] =          '<a class="actionLink" href="javascript:void(0);" onclick="' + this.id + '.editTags(\'merge\'); return false;" title="Select two or more tags from tagcloud to merge">Merge</a>';
				if(!this.options.dialogWin)
					arrContent[arrContent.length] =          '&nbsp;| <a class="actionLink" href="javascript:void(0);" onclick="' + this.id + '.toggleEditor();" title="Close the edit drawer">Close</a>';
				arrContent[arrContent.length] =      '</div>';
				//if(!this.options.dialogWin && this.datasource.dioId != null)
				//	arrContent[arrContent.length] = '<span><a style="text-align:right;" href="javascript:void(0)" onclick="openTagCloudTray(\'select\',\''+ this.editFieldId +'\')">Select from Tag Cloud</a></span>';
				arrContent[arrContent.length] = '<div id="tc_confirmBox" style="padding:5px;"></div>';
				arrContent[arrContent.length] = '</div>';
				arrContent[arrContent.length] = '<div id="editControls">';
				arrContent[arrContent.length] =      '<ul class="tagCloudControlList">';
				arrContent[arrContent.length] =          '<li id="editorToggler" class="end"><a href="javascript:void(0);" onclick="' + this.id + '.toggleEditor();return false;"><span id="editlabel">Edit Tags</span></a></li>';
				arrContent[arrContent.length] =      '</ul>';
				arrContent[arrContent.length] = '</div>';
			}else if(this.options.mode.toLowerCase() == MODE_SELECT){
				arrContent[arrContent.length] = '<div id="editor" style="display: none;"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td style="width:100px;vertical-align:top;">Selected tags: &nbsp;</td><td><div id="' + this.editFieldId + '" class="editme"></div></td></tr></table>';
				arrContent[arrContent.length] =      '<div id="editorButtons"><input type="button" class="dekoh_button" onclick="' + this.id + '.selectTags(); return false;" value="Ok" /> &nbsp; <input type="button" class="dekoh_button" onclick="closeDialog(gDialogId); return false;" value="Cancel" /></div>';
				arrContent[arrContent.length] = '</div>';
				arrContent[arrContent.length] = '<div id="editControls">';
				arrContent[arrContent.length] =      '<ul class="tagCloudControlList">';
				arrContent[arrContent.length] =          '<li id="editorToggler" class="end"><a href="javascript:void(0);" onclick="' + this.id + '.toggleEditor();return false;"><span id="editlabel">Select Multiple Tags</span></a></li>';
				arrContent[arrContent.length] =      '</ul>';
				arrContent[arrContent.length] = '</div>';
			}
			arrContent[arrContent.length] = '</div>';

			$(this.targetdiv).innerHTML = arrContent.join("");

			this.setActiveStyleSheet(currentlyActiveTagCloudStyle);

			//changing the close event for dialog - refresh if any tags edited
			if(this.options.dialogWin){
				if($(gDialogId + '_close')){
					$(gDialogId + '_close').onclick = function(){
						trayTagCloud.closeDialogWindow();
					}
				}
			}

			this.minFreqLog = 0;
			this.maxFreqLog = 0;
			this.freqLogRange = 1;

			this.datasource.getTags();
			this.initAndViewTagCloud();
	},

	closeDialogWindow:function(){
		closeDialog(gDialogId);

		if(trayTagCloud.editedTags)
			document.location = document.location;
	},

	initAndViewTagCloud:function(){
		with(this){
			initTagCloud();
			setMinMaxTagFrequency();
			setTagFontSizes();
			updateTagView();
		}
	},

	isMinimalMode: function(){
		return (this.options.minimalMode.toLowerCase() == 'on');
	},

	sortByName: function(reverse, toggleText, listToSort){
		var sorted = new Array();

		if (listToSort){
			sorted = listToSort.sortBy(function(item){
                if(item)
                    return item.tagtitle.toLowerCase();
			});
		}else{
			var tags = (this.viewTags.length == 0) ? this.datasource.tags : this.viewTags;
			sorted = tags.sortBy(function(item){
                if(item)
                    return item.tagtitle.toLowerCase();
			});
		}

		if(!toggleText){
			this.setSortField(SORT_NAME);
			if (!reverse)
				setLabel('alphalabel', 'A-z');
			else
				setLabel('alphalabel', 'Z-a');
	    }

		this.viewTags = (reverse) ? sorted.reverse() : sorted;

		return this.viewTags;
	},

	sortByFreq: function(reverse){
		this.viewTags = new Array();
		this.viewTags = this.datasource.tags;

		var sorted = this.viewTags.sortBy(function(tag){
			return tag.freq; // should this be weight or freq?
		});

		this.viewTags = (reverse) ? sorted : sorted.reverse();

		this.filterByUsage(this.options.currusagefilter);	//extract tags by current usage filter

		this.extractTopXTags(-1);
		this.setMinMaxTagFrequency();
		this.setTagFontSizes();
		this.setSortField(SORT_FREQ);
	},

	sortByDate: function(reverse){
		this.viewTags = new Array();
		this.viewTags = this.datasource.tags;

		var sorted = this.viewTags.sortBy( function(tag,index){
			return new Date(tag.created);
		});
		this.viewTags = (reverse) ? sorted : sorted.reverse();

		this.filterByUsage(this.options.currusagefilter);	//extract tags by current usage filter
		
		this.extractTopXTags(-1);
		this.setMinMaxTagFrequency();
		this.setTagFontSizes();
		this.setSortField(SORT_DATE);
	},

	toggleTagLimit: function(){
		this.filterClick = 2;

		// make next item current
		this.options.tagsLimit = getNextItem(this.options.tagsLimit, this.limitsList);

		this.viewTags = new Array();
		this.viewTags = this.datasource.tags;

		switch (this.options.currentShowSort){
			case "Most used":
				var sorted = this.viewTags.sortBy(function(tag){
					return tag.freq; // should this be weight or freq?
				});

				this.viewTags = sorted.reverse();
				break;
			case "Least used":
				var sorted = this.viewTags.sortBy(function(tag){
					return tag.freq; // should this be weight or freq?
				});

				this.viewTags = sorted;
				break;
			case "Latest":
				var sorted = this.viewTags.sortBy( function(tag,index){
					return new Date(tag.created);
				});

				this.viewTags = sorted.reverse();
				break;
			case "Oldest":
				var sorted = this.viewTags.sortBy( function(tag,index){
					return new Date(tag.created);
				});
					
				this.viewTags = sorted;
				break;
		}

		this.filterByUsage(this.options.currusagefilter);	//extract tags by current usage filter

		this.extractTopXTags(-1);							//extract tags by tags limit
		this.setMinMaxTagFrequency();						//set min max frequency
		this.setTagFontSizes();
		
		// change label to the item after that
		setLabel('limitlabel', this.options.tagsLimit);
		this.updateTagView(false);
	},

	toggleUsageFilter: function(){
		this.filterClick = 1;

		this.options.currusagefilter = getNextItem(this.options.currusagefilter, this.usageList);

		this.viewTags = new Array();						//reset current viewTags array
		this.viewTags = this.datasource.tags;				//reload viewTags with datasource tags array
		this.filterByUsage(this.options.currusagefilter);	//extract tags by current usage filter

		switch (this.options.currentShowSort){
			case "Most used":
				var sorted = this.viewTags.sortBy(function(tag){
					return tag.freq; // should this be weight or freq?
				});

				this.viewTags = sorted.reverse();
				break;
			case "Least used":
				var sorted = this.viewTags.sortBy(function(tag){
					return tag.freq; // should this be weight or freq?
				});

				this.viewTags = sorted;
				break;
			case "Latest":
				var sorted = this.viewTags.sortBy( function(tag,index){
					return new Date(tag.created);
				});
				this.viewTags = sorted.reverse();
				break;
			case "Oldest":
				var sorted = this.viewTags.sortBy( function(tag,index){
					return new Date(tag.created);
				});
				this.viewTags = sorted;
				break;
		}

		this.extractTopXTags(-1);							//extract tags by tags limit
		this.setMinMaxTagFrequency();						//set min max frequency
		this.setTagFontSizes();								//set font sizes

		// change label to the next item
		setLabel('ulabel', this.options.currusagefilter);	//reset usage filter label
		this.updateTagView(false);							//update tag view
	},

    filterByUsage: function(filter){
		var lastWeek = new Date; with (lastWeek) setDate(getDate()-7);          //equivalent to lastWeek.setDate(getDate()-7) ?????
		var lastMonth = new Date; with (lastMonth) setMonth(getMonth()-1);
		var yesterday = new Date; with (yesterday) setHours(-24);
		var filteredTagList = new Array();
		var now = new Date();
	    var tags = new Array();

	    tags = this.viewTags;

	    switch(filter){
			case USG_24HOURS:
				filteredTagList = tags.findAll( function(tag){
					var birthDay = (new Date(tag.created)).getTime();
					return birthDay >= yesterday.getTime() && birthDay < now;
				});
				break;
			case USG_WEEK:
				filteredTagList = tags.findAll( function(tag){
					var birthDay = (new Date(tag.created)).getTime();
					return birthDay >= lastWeek.getTime() && birthDay < now;
				})
				break;
			case USG_MONTH:
				filteredTagList = tags.findAll( function(tag){
					var birthDay = (new Date(tag.created)).getTime();
					return birthDay >= lastMonth.getTime() && birthDay < now;
				})
				break;
			case USG_ALL:
			default:
				filteredTagList = tags; // return ALL tags
				break;
		}
	    this.viewTags = filteredTagList;
	},

    toggleSorting: function(currSortField, isAscending){
	    this.filterClick = 4;
		var bReverse = (this.getSortOrder() == ORDER_REVERSE);
		//toggle (asc/desc) sorting order
		this.setSortOrder(!bReverse);
		var sLabel = bReverse? 'A-z' : 'Z-a';

		setLabel('alphalabel', sLabel);
		this.updateTagView(false);
	},

	toggleShowSorting: function(){
		this.filterClick = 3;
		this.options.currentShowSort = getNextItem(this.options.currentShowSort, this.sortToShowList);

		switch (this.options.currentShowSort){
			case "Most used":
				this.sortByFreq(false);
				break;
			case "Least used":
				this.sortByFreq(true);
				break;
			case "Latest":
				this.sortByDate(false);
				break;
			case "Oldest":
				this.sortByDate(true);
				break;
		}

		setLabel('sortShowing', this.options.currentShowSort);
		this.updateTagView(false);
	},

	updateTagView: function(useFilter){
		if(useFilter || this.firstTimeInvocation){
			this.setMinMaxTagFrequency();
			this.setTagFontSizes();
			this.sortByFreq(false);
		}

		if (this.getView() == VIEW_LIST)
			this.refreshTagList(this.options.contentdiv, useFilter);
		else
			this.refreshTagCloud(this.options.contentdiv, useFilter);

		if((this.options.mode == MODE_EDIT || this.options.mode == MODE_SELECT) && this.options.dialogWin){
			if(this.editorOpen || (this.options.mode == MODE_SELECT)){
                if(this.firstTimeInvocation)
                	this.toggleEditor();
            }

			this.initEditMode();
		}

		if(this.firstTimeInvocation)
			this.firstTimeInvocation=false;

		this.setActiveStyleSheet(currentlyActiveTagCloudStyle);
	},

	setMinMaxTagFrequency:function(){
		var arrFrequencies = new Array();
        if(this.viewTags.length == 0)
            this.viewTags = this.datasource.tags;

        this.viewTags.each(function(memberTag,index){
            if(memberTag)
                arrFrequencies[index] = Math.max(1,memberTag.freq);
        });

		this.minFreqLog = Math.log(arrFrequencies.min());
		this.maxFreqLog = Math.log(arrFrequencies.max());
		this.freqLogRange = Math.max(1,(this.maxFreqLog - this.minFreqLog));    //to avoid "divide by 0" exception
	},

	extractTopXTags: function(filterClick){
		var tagLimit = this.options.tagsLimit;
		var tags = new Array();

		if(filterClick == 4 || filterClick == 0)
			tags = this.datasource.tags;
		else
			tags = (this.viewTags.length == 0 ) ? this.datasource.tags : this.viewTags;

		var viewTags = new Array();

		if(tagLimit != 'All'){
			for(var tagIndex = 0;tagIndex < tagLimit;tagIndex++)
				if(tags[tagIndex])
					viewTags[tagIndex] = tags[tagIndex];
		}else{
			viewTags = tags;
		}

		this.viewTags = viewTags;
	},

	setTagFontSizes: function(){
		var tags = this.viewTags;
		var cloudObj = this;

		tags.each(function(member,index){
            if(member){
                member.fontSize = tc_FontSizeLookup(cloudObj,member.freq);
	        }
		})
	},

	refreshTagCloud: function(id, bFilter){
		var cldDiv = $(id);

		if(bFilter)
			this.setTagFontSizes();

		var theTags = new Array();
		for(var i=0;i<this.viewTags.length;i++){
			theTags.push(this.viewTags[i]);
		}

		if(cldDiv){
			cldDiv.className = '';
		}

		var arrInnerContent = new Array();
		var totalTags = theTags.length; // limit no. of tags
		totalTags = (this.options.tagsLimit > 0 && this.options.tagsLimit <= totalTags) ? this.options.tagsLimit : totalTags;

		if (totalTags > 0){
	        // getting the list to show and sorting to alphabetical order
	        var tmp = new Array();
	        for(var j =0; j < totalTags; j++)
				tmp.push(theTags[j]);

			var bReverse = (ORDER_REVERSE == this.options.sortOrder);
			tmp = this.sortByName(bReverse, true, tmp);

			theTags = tmp;
	        var separatorHtml = '<span class="separator">' + this.options.tagSeparator + '</span>';
	        var styleClass = 0;
			var tagFontSize = 12;

			for (var i=0; i < totalTags; i++){
                if(theTags[i]){
	                if(!this.options.textSizeOn){
	                    tagFontSize = 12;
		                styleClass = "tag1";
	                }else{
	                    tagFontSize = theTags[i].fontSize;
	                    styleClass = this.getStyleForRank(theTags[i].freq);
		            }

					arrInnerContent[arrInnerContent.length] = '<span class="' + styleClass + '"><a name="' + this.aTag + '" href="' + theTags[i].url + '"';
                    if (this.options.textSizeOn)
                        arrInnerContent[arrInnerContent.length] = ' style="font-size:'+ tagFontSize +'px;"';
                    if(this.options.tagLinkWindow!="_self")
                        arrInnerContent[arrInnerContent.length] =' target="'+this.options.tagLinkWindow+'"';
                    
                    arrInnerContent[arrInnerContent.length] = '>' + theTags[i].tagtitle + '</a></span>';
                    if (this.options.rankOn)
                        arrInnerContent[arrInnerContent.length] = '<span class="tagslistwt">(' + theTags[i].freq + ')</span>';

                    if (i != totalTags - 1)
                        arrInnerContent[arrInnerContent.length] = separatorHtml; // drop the last separator
               }
            }
        } else {
            arrInnerContent[arrInnerContent.length] = '<span class="notagserror">No tags</span>';
        }

		if(cldDiv){
			cldDiv.innerHTML = arrInnerContent.join("");
			Effect.Appear(id, {duration: .25});             //FIXME : problem here with large amount of data - takes very long time
		}
	},

	refreshTagList: function(id, bFilter){
		var cloudDiv = $(id);
		var arrInnerContent = new Array();
		arrInnerContent[arrInnerContent.length] = '<table class="listview" width="95%" align="center">\n';

		// if we're using a month/week filter,
		// then use the alternate filtered tag array

		var theTags = (bFilter) ? this.viewTags : this.datasource.tags;
		arrInnerContent[arrInnerContent.length] = '<thead><tr><th>Tags</th>';

        if (!this.isMinimalMode())
            arrInnerContent[arrInnerContent.length] = '<th>Popularity</th><th>Added On</th></tr>';

		arrInnerContent[arrInnerContent.length] = '</thead><tbody>\n';

		if(cloudDiv){
	        cloudDiv.style.display = 'none';
			cloudDiv.className = "list";
	    }

		var totalTags = theTags.length; // limit no. of tags
		totalTags = (this.options.tagsLimit > 0 && this.options.tagsLimit <= totalTags) ? this.options.tagsLimit : totalTags;

		if (totalTags > 0){
	        // getting the list to show and sorting to alphabetical order
	        var tmp = new Array();
	        for(var j = 0;j < totalTags;j++)
				tmp.push(theTags[j]);

			var bReverse = (ORDER_REVERSE == this.options.sortOrder);
	        tmp = this.sortByName(bReverse,true,tmp);

	        theTags = tmp;

            for (var i=0; i < totalTags; i++){
	            var tagDate = new Date();

	            if(theTags[i].created)
		            tagDate = new Date(theTags[i].created);

	            var mm = tagDate.getMonth() + 1;
                var dd = tagDate.getDate();
                var yyyy = tagDate.getFullYear();
                arrInnerContent[arrInnerContent.length] = '<tr><td><span class="tag"><a name="' + this.aTag + '" href="'+ theTags[i].url +'">'+ theTags[i].tagtitle+'</a></span></td>';

	            if (!this.isMinimalMode()){
                    arrInnerContent[arrInnerContent.length] = '<td>'+ theTags[i].freq +'</td><td>' + mm + '/' + dd + '/' + yyyy + '</td></tr>\n';
                }
            }
        } else {
            arrInnerContent[arrInnerContent.length] = '<tr><td><span class="notagserror">No tags</span></td></tr>';
        }
        arrInnerContent[arrInnerContent.length] = "</tbody></table>\n";

		if(cloudDiv){
			cloudDiv.innerHTML = arrInnerContent.join("");
			Effect.Appear(id, {duration: .25});
		}
	},

	editAddTags: function(){
		this.discardEditConfirmBox();       //if confirm box is already open (for other actions like merge/rename etc.)

		// check if user has entered tags
		var elt = $(this.editFieldId);
		var eltValue = (elt.tagName.toLowerCase() == 'input') ? elt.value : elt.innerHTML;
		if(eltValue == '' ){
			elt.focus();
			this.editSuccess = false;
			return false;
		}else{
			var editField = $(this.editFieldId);
			var editFieldVal = trim(editField.value);
			this.datasource.addTags(editFieldVal);                  //adding the tag to DB
			this.editedTags = true;

			var toAddTags = editFieldVal.split(',');
			toAddTags = toAddTags.each(function(member,index){
				toAddTags[index] = trim(unescape(member));
			});

			var newlyAddedTags = new Array();
			var isNewTagAdded = false;
			var tempTagsArray = this.viewTags;
			var tagCloudObjRef = this;

			toAddTags.each(function(memberTag,tagIndex){
				var matchingTag = null;
				matchingTag = tempTagsArray.find(function(viewTagMember,viewTagIndex){
					if(viewTagMember)
						return trim(memberTag) == trim(viewTagMember.tagtitle);
				});

				if(!matchingTag){
					if(memberTag != ''){
						newlyAddedTags[newlyAddedTags.length] = new oTag(memberTag, 0, tagCloudObjRef.datasource.getUrl(memberTag), new Date().getTime(), 0);
						isNewTagAdded = true;
					}
				}
			});

			for(var i = 0; i < newlyAddedTags.length;i++)
				this.viewTags[this.viewTags.length] = newlyAddedTags[i];

			if(!this.options.dialogWin)
				this.toggleEditor();

			if(isNewTagAdded){
				this.filterClick = -1;       //setting to non-zero
				this.setMinMaxTagFrequency();
				this.setTagFontSizes();
				this.updateTagView(false);
			}

			if(editField.tagName.toLowerCase() == 'input')
				editField.value = '';
			else
				editField.innerHTML = '';
		}
	},

	selectTags: function(){
		var theTags = [];
		var editField = $(this.editFieldId);
		var theEntry = (editField.tagName == 'input') ? editField.value : editField.innerHTML;
		var returnTxtField = $(this.options.returnTxtFieldId);

		if (theEntry != ''){
			if(!this.options.dialogWin)
				this.toggleEditor();
			closeDialog(gDialogId);
			returnTxtField.value = (returnTxtField.value != '') ? (returnTxtField.value + ', ' + theEntry) : theEntry;
		}
	},

	editTags: function(strAction){
		switch(strAction){
			case 'add':
				this.editAddTags();
				break;
			case 'delete':
				this.editDelete();
				break;
			case 'rename':
				this.editRename();
				break;
			case 'merge':
				this.editMerge();
				if(this.editSuccess)
					this.datasource.mergeTags(trim($(this.editFieldId)));
				break;
			default:
				break;
		}
	},

	editMerge: function(){
		this.getEditMergeConfirmation("Merge as ",'commitEditMerge');
	},

	getEditMergeConfirmation:function(strQuestion,funcRef){
		var strInputVal = $(this.editFieldId).value;
		var arrSelectedTags = strInputVal.split(',');
		arrSelectedTags = arrSelectedTags.each(function(member,index){		//removes %20 or spaces
				arrSelectedTags[index] = trim(unescape(member));
			});
		if(arrSelectedTags.length > 1 && trim(arrSelectedTags[1]) != ''){
			if(oTagCloudDialog)
				oTagCloudDialog.setStatusMsg('');
			var queFrame = $('tc_confirmBox');
			queFrame.style.display = 'block';
			var queHTML = new Array();

			queHTML[queHTML.length] = strQuestion;
			queHTML[queHTML.length] =   '<input type="text" id="tc_confirmInput" maxlength="60" class="dekoh_textfield" style="width:75px;" />';
			queHTML[queHTML.length] =   '<a style="margin-left: 10px;" href="javascript:void(0);" onclick="' + this.id + '.' + funcRef + '()">Ok</a> &nbsp;|&nbsp; ';
			queHTML[queHTML.length] =   '<a href="javascript:void(0);" onclick="' + this.id + '.discardEditConfirmBox()">Cancel</a>';

			queFrame.innerHTML = queHTML.join("");
		}else
			if(oTagCloudDialog)
				oTagCloudDialog.setStatusMsg('error','Please select more than one tags to merge');
	},

	commitEditMerge:function(){
		var theEntry = ($(this.editFieldId).value);
		var oldTagNames = theEntry.split(',');
		oldTagNames = oldTagNames.each(function(member,index){
				oldTagNames[index] = trim(unescape(member));
			});
		var tagCloud = this;
		var newTagName = trim($('tc_confirmInput').value);

		if(oTagCloudDialog)
			oTagCloudDialog.setStatusMsg('');

		if (newTagName != ""){
			this.datasource.mergeTags(oldTagNames, newTagName);
			this.editedTags = true;

			for(var ii = 0; ii < oldTagNames.length ; ii++){
				var tag = this.getTagByName(trim(oldTagNames[ii]));
				if(ii == 0){
					tag.tagtitle = newTagName;
					tag.url = tag.tagtitle;			
				}else{
					this.viewTags = this.viewTags.without(tag);
				}
			}
			this.firstTimeInvocation = false;			//patch
			this.updateTagView(false);                   //updating tag view

			if(oTagCloudDialog)
				oTagCloudDialog.setStatusMsg('success','The tags: "'+ oldTagNames.join(', ') + '" have been merged as "' + newTagName + '"');

			if(!this.options.dialogWin)
				this.toggleEditor();
		}else{
			if(oTagCloudDialog)
				oTagCloudDialog.setStatusMsg('error','Please enter the new tag name');
		}
	},

	editRename: function(){
		this.getEditRenameConfirmation("Rename as ",'commitEditRename');
	},

	getEditRenameConfirmation:function(strQuestion,funcRef){
		var strInputVal = $(this.editFieldId).value;
		if(strInputVal.length > 0){
			if(oTagCloudDialog)
				oTagCloudDialog.setStatusMsg('');
			var queFrame = $('tc_confirmBox');
			queFrame.style.display = 'block';
			var queHTML = new Array();

			queHTML[queHTML.length] = strQuestion;
			queHTML[queHTML.length] =   '<input type="text" id="tc_confirmInput" class="dekoh_textfield" style="width:75px;" />';
			queHTML[queHTML.length] =   '<a style="margin-left: 10px;" href="javascript:void(0);" onclick="' + this.id + '.' + funcRef + '()">Ok</a> &nbsp;|&nbsp; ';
			queHTML[queHTML.length] =   '<a href="javascript:void(0);" onclick="' + this.id + '.discardEditConfirmBox()">Cancel</a>';

			queFrame.innerHTML = queHTML.join("");
		}else
			if(oTagCloudDialog)
				oTagCloudDialog.setStatusMsg('error','Please select tag(s) to rename');
	},

	commitEditRename:function(){
		if(oTagCloudDialog)
			oTagCloudDialog.setStatusMsg('');
		var selectedTag = trim($(this.editFieldId).value);
		var confirmBoxEntry = trim($('tc_confirmInput').value);
		var tagCloud = this;
		var multipleTags = false;

		if (selectedTag != ''){
			if(selectedTag.indexOf(',') != -1){
				if(oTagCloudDialog)
					oTagCloudDialog.setStatusMsg('error','Please select single tag to rename');
			}else{
				if(confirmBoxEntry.length > 0){
					this.editedTags = true;
					this.datasource.renameTag(selectedTag, confirmBoxEntry);
					if(oTagCloudDialog)
						oTagCloudDialog.setStatusMsg('success','The tag "'+ selectedTag + '" occurances have been replaced with "' + confirmBoxEntry +'"');

					if(!this.options.dialogWin)
						this.toggleEditor();

					var tag = this.getTagByName(selectedTag);
					tag.tagtitle = confirmBoxEntry;
					this.updateTagView();                   //updating tag view
				}
			}
		}
	},

	editDelete: function(){
		this.getEditDeleteConfirmation("Are you sure you want to DELETE the selected tag(s)?",'commitEditDelete');
	},

	getEditDeleteConfirmation:function(strQuestion,funcRef){
		var strInputVal = $(this.editFieldId).value;
		if(strInputVal.length > 0){
			if(oTagCloudDialog)
				oTagCloudDialog.setStatusMsg('');
			var queFrame = $('tc_confirmBox');
			queFrame.style.display = 'block';
			var queHTML = new Array();

			queHTML[queHTML.length] = strQuestion;
			queHTML[queHTML.length] =   '<a style="margin-left: 10px;" href="javascript:void(0);" onclick="' + this.id + '.' + funcRef + '()">Yes</a> &nbsp;|&nbsp; ';
			queHTML[queHTML.length] =   '<a href="javascript:void(0);" onclick="' + this.id + '.discardEditConfirmBox()">No</a>';

			queFrame.innerHTML = queHTML.join("");
		}else
			if(oTagCloudDialog)
				oTagCloudDialog.setStatusMsg('error','Please select tag(s) to delete');
	},

	commitEditDelete:function(){
		var strInputVal = trim($(this.editFieldId).value);
		if(oTagCloudDialog)
			oTagCloudDialog.setStatusMsg('');
		var theTags = new Array();
		var tagCloud = this;
		theTags = strInputVal.split(',');
		theTags = theTags.each(function(member,index){ 			//remove %20 or spaces
				theTags[index] = trim(unescape(member));
			});

		this.datasource.deleteTags(theTags);
		this.editedTags = true;

		var matchingTag = false;
		var tagCloudRef = this;

		theTags.each(function(member,index){
			matchingTag = tagCloudRef.getTagByName(trim(member));
			if(matchingTag)
				tagCloudRef.viewTags = tagCloudRef.viewTags.without(matchingTag);
		});

		var editField = $(this.editFieldId);

		if(editField.tagName.toLowerCase() == 'input')
			editField.value = '';
		else
			editField.innerHTML = '';

		this.discardEditConfirmBox();

		if(!this.options.dialogWin)
			this.toggleEditor();

		this.filterClick = -1;      //setting to non-zero value

		if(this.viewTags.length > 0)
		this.updateTagView(true);
		else
			$(this.options.contentdiv).innerHTML = '<span class="notagserror">No tags</span>';
	},

	getTagByName:function(tagName){
		var theTags = this.viewTags;
		var matchingTag = false;

		matchingTag = theTags.find(function(tag,index){
			return trim(tag.tagtitle) == trim(tagName);
		});

		return matchingTag;
	},

	discardEditConfirmBox:function(){
		var confirmBox = $('tc_confirmBox');
		confirmBox.innerHTML = '';
		confirmBox.style.display = 'none';
	},

	// starts and ends edit mode
	toggleEditor: function(){
		if(this.optionsOpen)
			this.toggleMoreOptions();

		var elt = $('editor');
		new Effect.toggle(elt, 'blind', {duration:0.25});

		if (this.options.mode.toLowerCase() == MODE_EDIT){
			if (this.editorOpen && !this.options.dialogWin){
				this.endEditMode();
				new Effect.toggle($('editControls'), 'appear',{duration:0.5})
			} else {
				this.initEditMode();
				new Effect.toggle($('editControls'), 'appear',{duration:0.1})
			}
		} else if (this.options.mode.toLowerCase() == MODE_SELECT){
			if (this.editorOpen && !this.options.dialogWin){
				this.endEditMode();
				new Effect.toggle($('editControls'), 'appear',{duration:0.5})
			} else {
				this.initEditMode();
				new Effect.toggle($('editControls'), 'appear',{duration:0.5})
			}
		}

		this.editorOpen = !this.editorOpen;
	},

	toggleColors: function(){
		this.options.colorsOn = !this.options.colorsOn;
		if (!this.options.colorsOn){
			this.hideColors();
		}else{
			this.showColors();
		}
	},

	toggleTextSize: function(){
		this.options.textSizeOn = !this.options.textSizeOn;
		if (!this.options.textSizeOn){
			this.removeTextSizes();
		}else{
			this.applyTextSizes();
		}
	},

	// opens/closes the more options drawer
	toggleMoreOptions: function(){
		if(this.editorOpen && !this.options.dialogWin)
			this.toggleEditor();

		if(this.options.dialogWin)
			this.resizeTagContainer(34);

		var elt = $('moreOptions');
		new Effect.toggle(elt, 'blind', {duration:0.25});
		var eltLabel = $('showmorelabel');
		if (this.optionsOpen){
			eltLabel.innerHTML = 'More options &raquo;';
			eltLabel.title = 'Opens the options drawer';
		}else{
			eltLabel.innerHTML = 'Fold options &laquo;';
			eltLabel.title = 'Closes the options drawer';
		}
		this.optionsOpen = !this.optionsOpen;
	},

	resizeTagContainer:function(iResizeBy){
		var tagContainerDiv = $(this.options.contentdiv + '_holder');
		if(tagContainerDiv.getAttribute('compressed') == "true"){
			tagContainerDiv.style.height = (parseInt(tagContainerDiv.style.height) + iResizeBy) + 'px';
			tagContainerDiv.setAttribute('compressed','false');
		}else{
			tagContainerDiv.style.height = (parseInt(tagContainerDiv.style.height) - iResizeBy) + 'px';
			tagContainerDiv.setAttribute('compressed','true');
		}
	},

	toggleFrequency: function(){
		this.options.rankOn = !this.options.rankOn;
		$('freqchk').checked = this.options.rankOn;
		if (this.getView() != VIEW_LIST)
			this.updateTagView(false);
	},

	// inserts an onclick handler into each tags <SPAN> elt
	// so clicking the link will add to editor text box
	initEditMode: function(){
		var tagsList = document.getElementsByName(this.aTag);

		if(typeof(tagsList) != 'undefined'){
			var nTags = tagsList.length-1;
			for (var i = 0; i <= nTags; i++){
				tagsList[i].parentNode.onclick = this.swapText;
			}
		}

		var editField = $(this.editFieldId);

		if(editField.tagName.toLowerCase() == 'input'){
			editField.value = '';
		}else{
			editField.innerHTML = '';
		}
	},

	endEditMode: function(){
		var tagsList = document.getElementsByName(this.aTag);
		if(typeof(tagsList) != 'undefined')
		{
			var nTags = tagsList.length-1;
			for (var i = 0; i <= nTags; i++){
				tagsList[i].parentNode.onclick = '';
			}
		}
	},

	//
	swapText: function(){
		var tagCloud = (this.childNodes[0].name == 'aTag_page') ? pageTagCloud : trayTagCloud;
		var elt = $(tagCloud.editFieldId);
		var tagText = this.firstChild.innerHTML;
		var eltValue = '';

		if(elt.tagName.toLowerCase() == 'input'){
			if(!tagCloud.isDuplicate(elt.value,tagText)){
				var sep = (elt.value != '')?', ':'';
				eltValue = elt.value + sep + tagText;;
				elt.value = eltValue;
			}
		}else{
			if(!tagCloud.isDuplicate(elt.innerHTML,tagText)){
				var sep = (elt.innerHTML != '')?', ':'';
				eltValue = elt.innerHTML + sep + tagText;;
				elt.innerHTML = eltValue;
			}
		}

		return false;
	},

	isDuplicate:function(selectedTags,currentTag){
		var isDuplicate = false;
		var arrSelectedTags = selectedTags.split(',');
		arrSelectedTags = arrSelectedTags.each(function(member,index){		//removes %20 or spaces
				arrSelectedTags[index] = trim(unescape(member));
			});

		isDuplicate = arrSelectedTags.find(function(member,index){
            return trim(member.toLowerCase()) == trim(currentTag.toLowerCase());
		});

		return isDuplicate;
	},

	addTag: function(tagsArray){
		var tagCloudObjRef = this;
		var matchFound = false;
		var tag = null;

		tagsArray.each(function(member,index){
			matchFound = tagCloudObjRef.viewTags.find(function(viewTag,viewTagIndex){
				return trim(viewTag.tagtitle) == trim(member);
			});

			if(!matchFound){
				tag = new oTag(member, 0, member, new Date(), 0);
				tagCloudObjRef.viewTags.push(tag);
			}
		});

		this.setMinMaxTagFrequency();
		this.setTagFontSizes();
		this.updateTagView();
	},

	getTag: function(idx){
		return this.datasource.tags[idx];
	},

	getSortOrder: function(){
		return this.options.sortOrder;
	},

	// order = true or false
	// if true set to ORDER_REVERSE, otherwise ORDER_ASC
	setSortOrder: function(order){
		this.options.sortOrder = (order) ? ORDER_REVERSE : ORDER_ASC;
	},

	getSortField: function(){
		return this.options.sortField;
	},

	setSortField: function(field){
		this.options.sortField = (field > 0) ? field : 1;
	},

	getView: function(){
		return (this.options.tagView) ? this.options.tagView : VIEW_CLOUD;
	},

	setView: function(view){
		this.options.tagView = view;
	},

	getStyleForRank: function(wt){
		// [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 24, 28, 30, 32, 35, 38, 40];	//font sizes
		switch (tc_FontSizeLookup(this,wt)){
			case 9:
			case 10:
			case 11:
			case 12:
			case 13:
				return 'tag1';
				break; // <- I don't need this do I?
			case 14:
			case 15:
			case 16:
			case 17:
			case 18:
				return 'tag2';
				break; // <- No, I mean seriously...
			case 19:
			case 20:
			case 22:
			case 24:
			case 28:
				return 'tag3';
				break; // <- ok I give up *sigh*
			default:
				return 'tag4';
				break;
		}
	},

	initTagCloud: function(data){
			if(this.viewTags.length == 0)
				this.viewTags = this.datasource.tags;

			switch (this.getSortField()){
				case SORT_NAME:
					this.sortByName(false);
					break;
				case SORT_FREQ:
					this.sortByFreq(false);
					break;
				case SORT_DATE:
					this.sortByDate(false);
					break;
				default:
					this.sortByName(false);
					break;
			}
    },

	viewAsList: function(){
		this.filterClick = 5;
		this.setView(VIEW_LIST);
		this.updateTagView(true);
	},

	viewAsCloud: function(){
		this.filterClick = 5;
		this.setView(VIEW_CLOUD);
		this.updateTagView(false);
	},

	showColors: function(){
        this.setActiveStyleSheet(this.currStyleSheet);
        $('colchk').checked = true;
		this.options.colorsOn = true;
	},

	hideColors: function(){
        this.setActiveStyleSheet(0);
        $('colchk').checked = false;
		this.options.colorsOn = false;
	},

	removeTextSizes: function(){
		$('txtchk').checked = false;
		this.options.textSizeOn = false;
		if (this.getView() != VIEW_LIST)
			this.updateTagView(false);
	},

	applyTextSizes: function(){
		$('txtchk').checked = true;
		this.options.textSizeOn = true;
		if (this.getView() != VIEW_LIST)
			this.updateTagView(false);
	},

	setPrevStyleSheet: function(){
		var idx = currentlyActiveTagCloudStyle;
        if (idx != -1){
			if (idx > 0){ // if we're at the first style
				//setActiveStyleSheet(ssList[idx-1]);
                this.setActiveStyleSheet(idx-1);
                this.currStyleSheet = idx-1;
			} else { // rotate to the last style
				this.setActiveStyleSheet(this.options.noOfStyles-1);
				this.currStyleSheet = this.options.noOfStyles-1;
			}
		} else { //set default style sheet if current stylesheet is not set
            this.setActiveStyleSheet(0);
            this.currStyleSheet = 0;
		}
		this.options.colorsOn = true;
		$('colchk').checked = true;
	},

	setNextStyleSheet: function(){
		var idx = currentlyActiveTagCloudStyle;
		if (idx != -1){
			if (idx < this.options.noOfStyles-1){// if last style is current ss
				this.setActiveStyleSheet(idx+1);
				this.currStyleSheet = idx+1;
			} else { // then rotate to first ss
				this.setActiveStyleSheet(0);
				this.currStyleSheet = 0;
			}
		} else { //set default style sheet if current stylesheet is not set
			this.setActiveStyleSheet(0);
			this.currStyleSheet = 0;
		}
		this.options.colorsOn = true;
		$('colchk').checked = true;
	},

    setActiveStyleSheet:function(index){
        var cloudContentDiv = $(this.options.contentdiv);
        var cloudContentDivHolder = $(this.options.contentdiv + '_holder');

        if (cloudContentDiv){
            if (!parseInt(index))
                index = 0;

            cloudContentDiv.className = "cloudContentStyle" + (parseInt(index)+1);

            if(cloudContentDivHolder)
                cloudContentDivHolder.className = "cloudContentStyle" + (parseInt(index)+1) + '_holder';
        }

        currentlyActiveTagCloudStyle = index;
    }
}

function isDefined(variable){
	return (typeof(window[variable]) != "undefined");
}

function trim(str){
	try{
		return str.replace(/^\s+/,'').replace(/\s+$/,'');
	}catch(e){
	}
}

function setLabel(id, txt){
	if ($(id)){
		$(id).innerHTML = txt;
	}
}

function getNextItem(curItem, itemList){
	return itemList[(itemList.indexOf(curItem)+1)%itemList.length]
}

function addLoadEvent(func){
	var oldonload = window.onload;
	if (typeof window.onload != 'function'){
		window.onload = func;
	} else {
		window.onload = function(){
			if (oldonload){
				oldonload();
			}
			func();
		}
	}
}

function toDisableLink(field){
	if(field == "mostused"){
		$("showSortMostUsed").onclick = function(){return false;};
		$("showSortLeasttUsed").onclick = function(){goTagCloud.sortByFreq(true); return false;};
		$("showSortLatest").onclick = function(){goTagCloud.sortByDate(false); return false;};
		$("showSortOldest").onclick = function(){goTagCloud.sortByDate(true); return false;};
	}else if(field == "leastused"){
		$("showSortMostUsed").onclick = function(){goTagCloud.sortByFreq(false); return false;};
		$("showSortLeasttUsed").onclick = function(){return false;};
		$("showSortLatest").onclick = function(){goTagCloud.sortByDate(false); return false;};
		$("showSortOldest").onclick = function(){goTagCloud.sortByDate(true); return false;};
	}else if(field == "latest"){
		$("showSortMostUsed").onclick = function(){goTagCloud.sortByFreq(false);return false;};
		$("showSortLeasttUsed").onclick = function(){goTagCloud.sortByFreq(true); return false;};
		$("showSortLatest").onclick = function(){ return false;};
		$("showSortOldest").onclick = function(){goTagCloud.sortByDate(true); return false;};
	}else if(field == "oldest"){
		$("showSortMostUsed").onclick = function(){goTagCloud.sortByFreq(false);return false;};
		$("showSortLeasttUsed").onclick = function(){goTagCloud.sortByFreq(true); return false;};
		$("showSortLatest").onclick = function(){goTagCloud.sortByDate(false); return false;};
		$("showSortOldest").onclick = function(){ return false;};
	}
}

//return font size depending on the frequency rank of the tag
function tc_FontSizeLookup(tagCloud,iFreq){
	var minFontSize = 12;           //minimum font size
	var maxFontSize = 40;           //maximum font size
	iFreq = Math.max(1,iFreq);
	var iRatio = (Math.log(iFreq) - tagCloud.minFreqLog) / tagCloud.freqLogRange;

	return minFontSize + Math.round(((maxFontSize - minFontSize) * iRatio));
}

var oTag = Class.create();
oTag.prototype = {
	initialize: function(tName, tFreq, tUrl, tDate, tRank){
		this.tagtitle = new String(tName);
		this.freq = tFreq; // no. of occurances of this tag
		this.freqLog = Math.log(tFreq);
		this.url = tUrl;

		this.created = tDate;
		//this.rank = 9; // remove this after we implement percentile ranking
		this.rank = tRank;
		this.fontSize = 0;
	}
};
