
SortableManager = function () { 
	this.thead = null; 
	this.tbody = null; 
	this.columns = []; 
	this.rows = []; 
	this.sortState = {}; 
	this.sortkey = 0; 
	this.xml_url = xml_url;
}; 

function findqi2(){
	var cname = this.getAttribute('alt');
	// alert(cname);
	return true;
}

function quotemeta (string) {
    return string.replace(/(\W)/, "\\$1");
}
mouseOverFunc = function () { addElementClass(this, "over"); }; 
mouseOutFunc  = function () { removeElementClass(this, "over"); }; 
 
ignoreEvent = function (ev){ 
	if( ev && ev.preventDefault ){ 
		ev.preventDefault(); 
		ev.stopPropagation(); 
	}else if(typeof(event) != 'undefined'){ 
		event.cancelBubble = false; 
		event.returnValue = false; 
	} 
}; 

update(SortableManager.prototype,{ 
	"initWithTable": function (table){ 
		// Ensure that it's a DOM element 
		table = getElement(table); 

		// Find the thead 
		this.thead = table.getElementsByTagName('thead')[0]; 

		// get the mochi:format key and contents for each column header 
		var cols = this.thead.getElementsByTagName('th'); 
		for( var i = 0; i < cols.length; i++ ){ 
			var node = cols[i]; 
            var attr = null; 
            try{ 
                attr = node.getAttribute("mochi:format"); 
            } catch (err) { 
                // pass 
            }
			var o = node.childNodes; 
			this.columns.push({ 
                "format": attr, 
                "element": node, 
                "proto": node.cloneNode(true)
            }); 
        }
		// scrape the tbody for data 
        this.tbody = table.getElementsByTagName('tbody')[0];
		var rows = this.tbody.getElementsByTagName('tr');
        for(var i = 0; i < rows.length; i++){ 
            // every cell 
            var row = rows[i]; 
            var cols = row.getElementsByTagName('td'); 
            var rowData = []; 
            for (var j = 0; j < cols.length; j++) { 
                // scrape the text and build the appropriate object out of it 
                var cell = cols[j]; 
                var obj = scrapeText(cell); 
                switch (this.columns[j].format) { 
                    case 'isodate':
                        obj = isoDate(obj);
                        break; 
                    case 'str': 
                        break; 
                    case 'istr': 
                        obj = obj.toLowerCase(); 
                        break;
                    // cases for numbers, etc. could be here 
                    default:
                        break; 
                } 
                rowData.push(obj); 
            } 
            // stow away a reference to the TR and save it 
            rowData.row = row.cloneNode(true); 
            this.rows.push(rowData);
        } 
 
        // do initial sort on first column 
        this.drawSortedRows(this.sortkey, false, false); 
	},

	// Return a sort function for click events
    "onSortClick": function (name) { 
        return method(this, function () { 
            log('onSortClick', name); 
            var order = this.sortState[name]; 
            if( order == null ){ 
                order = true; 
            }else if (name == this.sortkey){ 
                order = !order; 
            } 
            this.drawSortedRows(name, order, true); 
        }); 
    }, 
 
    "drawSortedRows": function(key, forward, clicked){
		log('drawSortedRows', key, forward); 
		this.sortkey = key; 
		// sort based on the state given (forward or reverse) 
		var cmp = (forward ? keyComparator : reverseKeyComparator); 
		this.rows.sort(cmp(key)); 
		// save it so we can flip next time 
        this.sortState[key] = forward; 
        // get every "row" element from this.rows and make a new tbody 
        var newBody = TBODY(null, map(itemgetter("row"), this.rows)); 
        // swap in the new tbody 
        this.tbody = swapDOM(this.tbody, newBody); 
        for (var i = 0; i < this.columns.length; i++) { 
            var col = this.columns[i]; 
            var node = col.proto.cloneNode(true); 
            // remove the existing events to minimize IE leaks 
            col.element.onclick = null; 
            col.element.onmousedown = null; 
            col.element.onmouseover = null; 
            col.element.onmouseout = null; 
            // set new events for the new node 
            node.onclick = this.onSortClick(i); 
            node.onmousedown = ignoreEvent; 
            node.onmouseover = mouseOverFunc; 
            node.onmouseout = mouseOutFunc; 
            // if this is the sorted column 
            if (key == i) { 
                // \u2193 is down arrow, \u2191 is up arrow 
                // forward sorts mean the rows get bigger going down 
                var arrow = (forward ? "▲" : "▼"); 
                // add the character to the column header 
                node.getElementsByTagName('SPAN')[0].appendChild(SPAN(null, arrow)); 
                if(clicked) node.onmouseover(); 
            } 
            // swap in the new th 
            col.element = swapDOM(col.element, node); 
        } 
    },

	'loadChannelList':function(){
		$('SearchForm').SearchText.value ="";
		replaceChildNodes(this.tbody);
		var req;
		if( window.XMLHttpRequest ){
			req = new window.XMLHttpRequest();
		}else if(window.ActiveXObject){
			try {
				req = new ActiveXObject("Msxml2.XMLHTTP");
			}catch(e){
				try{
					req = new ActiveXObject("Microsoft.XMLHTTP");
				}catch(e2){
				}
			}
		}
		if(!req){
			alert("この環境ではXMLHttpRequestを使えません");
			return;
		}

		var url = this.xml_url+"?"+Math.random();
		try{
			req.open("GET",url,true);
			var self = this;
			req.onreadystatechange = function(){
				if(req.readyState!=4) return;
				if(req.status >= 300 ){
					alert("status="+req.status);
					return;
				}

				try{
					var info = req.responseXML.getElementsByTagName('info')[0];
					replaceChildNodes('lastupdate',info.getAttribute("updatestr"));
					replaceChildNodes('counts1',"ユーザ数:"+info.getAttribute("users"));
					replaceChildNodes('counts2',"チャンネル数:"+info.getAttribute("channels")+"(公開"+info.getAttribute("public_channels")+",非公開"+info.getAttribute("non_public_channels")+")");
				}catch(e){}

				var tags=req.responseXML.getElementsByTagName('channel');
				var list = [];
				for(var i=0,ie=tags.length;i<ie;++i){
					var tag = tags[i];
					var item = {
						'active':parseInt(tag.getAttribute("active"),10),
						'users':parseInt(tag.getAttribute("users"),10),
						'name':tag.getAttribute("name"),
						'short':tag.getAttribute("short"),
						'sort':tag.getAttribute("sort"),
						'topic':tag.getAttribute("topic")
					};
					list.push(item);
				}
				list.sort(function(a,b){
					var i;
					i=(b.active -a.active);if(i) return i;
					i=(b.users  -a.users );if(i) return i;
					if(a.sort < b.sort ) return 1;
					if(a.sort > b.sort ) return -1;
					return 0;
				});
				self.rows = [];
				for( var i=0,ie=list.length;i<ie;i++ ){ 
					var src = list[i];
					var rowData = [src.active,src.users,src.sort];
					if( src.topic.match(/^↓(\-?\d*)/) ){
						var n=0;
						if( RegExp.$1 ) n = parseInt(RegExp.$1,10);
						if(rowData[0]>n) rowData[0] = n;
					}
					rowData.row = TR({}
						,TD({'nowrap':'nowrap','class':'clistnumber'},src.active)
						,TD({'nowrap':'nowrap','class':'clistnumber'},src.users)
						,TD({'nowrap':'nowrap','class':'clistname'}
							,A({'target':'_blank','alt':src.name,'href':"/qi2/qi2.html?utf8="+encodeURIComponent(src.name)},src.short)
							,DIV({'class':'clisttopic'},src.topic)
						)
					);
					self.rows.push(rowData);
				}
				// alert("rows has "+self.rows.length+" entry");
				// do initial sort on first column 
				self.drawSortedRows(self.sortkey, false, false);
			}
			req.send(null);
		}catch(e){
			for(var i in e) logError("getChannelList: "+i+":"+e[i]);
		}
	},
	'isearch':function(pattern) {
		var regex = new RegExp(quotemeta(pattern), "i");
		var list = this.tbody.getElementsByTagName('tr');
		for(var i=0,ie=list.length;i<ie;++i){
			var text = scrapeText(list[i].childNodes[2]);
			list[i].style.display= (text.match(regex)?'':"none");
		}
    }
});
 
var sortableManager = new SortableManager(); 


function pageSetup(){
	sortableManager.initWithTable('sortable_table');
	sortableManager.loadChannelList();
}


function btnSearch_Clicked(clear){
	if(clear) $('SearchForm').SearchText.value ="";
	sortableManager.isearch( $('SearchForm').SearchText.value );
}
