/*
@Author: Anthony Cashaw of http://elmwoodstrip.org?u=enknot
@Name: tc.widget.pageControl
@Version: 1.0 03/01/08
@Release: Unreleased
@Package: GrandRounds
@Description: Enables the control of large bodies of data in a limited space with ajax
@Param: ele The page refrence to HTML node that holds the paging elements
@Param: handler A function that fires upon clicking a records display texts
@Example: 
<code>
		var MyCatalog = new tc.widget.pageControl('#cataloged_shell', clickItem);
		
		function clickItem(e){
			alert('you clicked item number ' + this.id);
		}
</code>
*/
tc.widget.pageControl = function(ele, dHandler){
	
	if(!ele){
		throw("No element passed");
	}
		
	if((typeof(ele.myType) == 'function') && ele.myType() == 'tc.widget.pageControl'){
		return ele;
	}
	
	try{
		ele = $(ele);		
	}catch(e){
		sb.consol.dump(e);
	}
	
	if(ele.nodeName && ele.nodeName == 'DIV'){				
		tc.importProperties(this, ele);			
		ele.init();		
		ele.listHandler = (sb.typeOf(dHandler) == 'function')?dHandler:ele.listHandler;	
		return ele;
	}
};

tc.widget.pageControl.prototype = {
	
	/**
	@Name: tc.widget.pageControl.addElement
	@Description: Adds a non standard element to this control.  
	Control must exist in the markup before it is added in this fashion
	@Param: : object configuration object primative
	@Example:
	<code>
		var myControl = new tc.pagingControl('#fauxname');		
		
		myControl.addElement({
			suffix : 'button',
			events : {
				click : function(e){
					alert(this.value);			
				},				
				mouseup : function(e){
					alert(this.value);
				}
			}			
		});
	
	</code>
	*/
	
	
	addElement : function(args){
		
		if(!args.suffix){return 0;}
		
		var newele;
		
		newele = this[args.suffix] = $('#' + this.rootname + '_' + args.suffix);
		
		for(var i in args.events){
			if(sb.typeOf(args.events[i]) == 'function'){
				this.events[args.suffix + '_' + args.events[i]] = newele.event(i, args.events[i]);
			}
		}
	},		
	
	
	checkCategory : function(){		
		var that = this;		
		this.listby.$('a').forEach(function(a){ 						
			if(/selected/.test(a.className)){
				that.ccat = a.href.match(/\d*$/);							
			}
		});
	},
	
	clickListBy : function(e){ 
		var targ = sb.events.target(e);
		if(targ.nodeName == 'A'){
			sb.events.stopAndPrevent(e);	
			
			this.listby.$('a').forEach(function(a){ 
				a.className = a.className.replace(/selected/ig, '');
			});					
			
			targ.className += ' selected';
			this.ccat = targ.href.match(/\d*$/);
			this.update({page : 1, category : this.ccat});
			this.select.value = 'ALL';
		}
	},
	
	ctrlClick : function(e){ 
		var targ = sb.events.target(e);		
		if((targ.nodeName == 'A') && (/page-/.test(targ.href))){ 
			sb.events.stopAndPrevent(e);
			this.turnToPage(targ.href.replace(/.*\-/, ''));	
		}
	},
	
	controlClick : function(e){
		var targ = sb.events.target(e);	
		
		if(targ.nodeName == 'A'){
				sb.events.stopAndPrevent(e);				
				if(/page-/.test(targ.href)){
					this.turnToPage(targ.href.replace(/.*\-/, ''));	
				}else if(targ.className == 'detail'){
					this.listHandler(e);
				}
		}
		
	},
	
	ccat : null,
	
	cpage : -1,
	
	cselector : null, 
	
	currentSelectChange : function(e){
		var targ = sb.events.target(e);
		this.update({page : targ.value, category : this.ccat});			
	},
	
	debug : 0,
	
	
	/**
	@Name: tc.widget.pageControl.listHandler
	@Description: handles the event that rises when an item in this list is clicked
	*/
	listHandler : function(e){ 
		alert('details handler is not yet defined');
	},
	
	flip : function(id, bRelist){
		bRelist  = bRelist || 0;
		this.cselector = id;
		this.update({selector : id}, bRelist);
		this.cselector = 'ALL';
	},
	
	
	/**
	@Name: tc.widget.pageControl.getRootName
	@Description: Gets the root name for this object
	*/
	getRootName : function(){ 
		this.rootname = this.id.replace('_shell', '');
		return this.rootname;
	},
	
	init : function(){					
	this.getRootName();
		this.initElements();
		this.cselector = this.select.value;	
	},
	
	
	/**
	@Name: tc.widget.pageControl.initElements
	@Description: Gets the select element contained in parent div
	*/
	initElements : function(){ 
		var that = this;
				
		if(!this.rootname){
			//throw exception
			//DEBUG
			if(this.debug){
				sb.consol.log('no rootname for tc.paging object');
			}
			//throw('no rootname for tc.paging object');
			return;			
		}
		
		
		this.list = $('#'+this.rootname+'_list');
		this.prev = $('#'+this.rootname+'_prev');
		this.next = $('#'+this.rootname+'_next');
		this.current = (sb.$('#'+this.rootname+'_current'))?$('#'+this.rootname+'_current'):'';
		this.current_select = (sb.$('#'+this.rootname+'_current_select'))?$('#'+this.rootname+'_current_select'):'';
		this.total = $('#'+this.rootname+'_total');
		this.listby = sb.$('#'+this.rootname+'_listby');
		this.control = $('#'+this.rootname+'_control');

		this.select = $('#'+this.rootname+'_select');

		//events
		this.control.event('click', function(e){
			that.ctrlClick(e, that);
		});
		
		this.list.event('click', function(e){ 
			that.listHandler(e);
		});
		
		this.select.event('change', function(e){
			that.selectChange(e);
		});
		
		if(this.current_select){
			this.current_select.event('change', function(e){
				that.currentSelectChange(e);
			});
		}
		
		if(this.listby){
			this.listby = $(this.listby);
			this.listby.event('click', function(e){
				that.clickListBy(e);
			});
			this.checkCategory();
			
		}	
	},	
	
	initSelect : function(){ 
		var that = this;
		
		
		//clear
		this.select = null;
		if(this.events['select-change']){sb.events.remove(this.events['select-change']);}
		
		
		//build
		this.select = $('#'+this.rootname+'_select');
		this.events['select-change'] = this.select.event('change', function(e){
			that.selectChange(e, that);
		});
	},
	
	publicProps : [],
					
	rebuildPageSelect : function(aOlist){
		
		
		var that = this;
		var opt; 
		var tempSel = new sb.element({ 
			nodeName : 'SELECT',
			tag : 'SELECT',
			className: 'cpage pnums',
			id : that.rootname + '_temp'
		});
		
		
		
		aOlist.forEach(function(v){ 	
			tempSel.options[tempSel.options.length] = new sb.element({ 
				tag : 'option',
				innerHTML : v.text,
				value : v.value				
			});
			
			
			if(v.selected == 1){
				tempSel.value = v.value;
			}
		});
		
		tempSel.replace(that.current_select);
		tempSel.id = that.rootname+'_current_select';
		that.current_select = tempSel;
		that.current_select.event('change', function(e){
							that.currentSelectChange(e);
		});
		
		
	},
	
	rebuildSelect : function(aOlist){ 
		var that = this;
		var opt; 
		var backto = that.select.value;
		var len;
		var tempSel = new sb.element({ 
			nodeName : 'SELECT',
			tag : 'SELECT',
			className: 'letterselect',
			id : that.rootname + '_temp'
		});
		
		len = tempSel.options.length;
		
		try{
			tempSel.options[len] = new sb.element({ 
					tag : 'option',
					innerHTML : 'ALL',
					value :  'ALL'			
				});	
		
			aOlist.forEach(function(v){ 
				tempSel.options[tempSel.options.length] = new sb.element({  
					tag : 'option',
					innerHTML : v.text,
					value  : v.value
				});
			});
			
		}catch(e){
			sb.consol.dump(tempSel);
			sb.consol.dump(e);
		}
		
		tempSel.replace(that.select);
		tempSel.id = that.rootname+'_select';
		that.select = tempSel;
		that.select.event('change', function(e){
							that.selectChange(e, that);
						});
		that.select.value = backto;
	},
					
	rootname : null,
	
	selectChange : function(e){ 
		this.update({page : 1, category : this.ccat, selector : this.select.value}, 0);
	},
	
	turnToPage : function(page, bRelist){
		bRelist  = bRelist || 0;
		this.update({page : page, category : this.ccat, selector : this.cselector}, bRelist);			
	},
	
	myType : function(){
		return 'tc.widget.pageControl';
	},
	
	uid : -1, 
	
	update : function(args, bRelist){
		var that = this;
		bRelist  = bRelist || 1;
		//DEBUG
		if(this.debug){
			sb.consol.log('cselector: ' + this.cselector + ' cpage: ' + this.cpage + ' ccat: ' + this.ccat);
			sb.consol.dump(args);
		}
		
		if((this.cselector != args.selector) || (this.cpage != args.page) || this.ccat != args.category){
			var req = 'c=update_' + this.rootname;
			
			//sorting by ALL
			if(args.selector == 'ALL'){ args.selector = null;}
			
			//building the query string
			for(var i in args){
				if(args[i]){req += '&' + i + '=' + args[i];}
			}
			
			
			app.ajax = new sb.ajax({  
				url : '../data/process.php',
				format : 'json',
				data : req,
				handler : function(gutz){								
					
					//update plain inners
					that.list.innerHTML = gutz.list;
					that.prev.href = "#page-" + gutz.prev;
					that.next.href = "#page-" + gutz.next;								
					that.total.innerHTML = gutz.total;
					
					//update selection list
					if(bRelist && gutz.optlist){that.rebuildSelect(gutz.optlist);}
					
					
					//update page number list (when nessisary)
					if(that.current){
						that.current.innerHTML  = gutz.current;
					}else if(gutz.curr_ajax_list){
						
						if(gutz.curr_ajax_list.length != that.current_select.options.length){
							that.rebuildPageSelect(gutz.curr_ajax_list);
						}else{										
							that.current_select.value = gutz.current;
						}								
					}
				}
			}).fetch();
			app.ajax = null;
		}
		
		this.cpage = (args.page)?args.page:this.cpage;
		this.cselector = (args.selector)?args.selector:'ALL';
		//this.ccat = (args.category)?args.category:null;
	}
};