
//requires sector67 library in sector67.js

google.setOnLoadCallback(function () { sector67.loadCSS("/widgets/widget.css"); });

// *** EditableWidget *************************************

sector67.EditableWidget = function () {
	var cachePage;
	obj = {};
	
	obj.type="editable";
	obj.eventsMap = new Object();
	
	//fill that.element and that.refreshableElement based on that.id
	//don't just look off of id... if you're a child, then a parent refresh may have renamed your dom.  look based on wid info to find something with same type and id
	obj.findElement = function() {
		var that=this;
		
		widgetCrawl = function(el) {
			el.children().each(function(index,Element) {
				curEl=$(this);
				if(curEl.hasClass("widget")) {
					widInfo = that.getWidgetInfo(curEl);
					if (widInfo.type==that.type && widInfo.id==that.id) {
						//it's a match!
						that.element = curEl;
						return true;
					}
				} else {
					if (widgetCrawl(curEl)) return true;
				}
			});
			
			return false;
		};
		
		if(!widgetCrawl(that.parent.element)) that.element = $("#" + that.dom_id);
		
		
		that.findRefreshableElement();
	};
	
	obj.findRefreshableElement = function() {
		var that=this;
		that.refreshableElement = that.element.find("#refreshable");
		if(that.refreshableElement.length==0) that.refreshableElement=that.element;
	};
	
	
	//crawl tags with class "widget" to make children
	obj.findChildren = function() {
		var that=this;
		if (that.children.length>0) alert(that.dom_id + " setting children when not empty! count=" + that.children.length);
		that.children = new Array();
		//alert("enter find children");
		//helper function for crawling through children to find widgets
		widgetCrawl = function(el) {
			el.children().each(function(index,Element) {
				curEl=$(this);
				if(curEl.hasClass("widget")) {
					//widget!
					//find the widget info, make the child and push it.  don't traverse deeper
					//alert("make on " + curEl.attr('id'));
					that.makeChild(that.getWidgetInfo(curEl));
				} else {
					widgetCrawl(curEl);
				}
			});
		};
		
		widgetCrawl(that.element);
	};
	
	//make a child widget given widInfo obtained using obj.getWidgetInfo
	obj.makeChild = function (widInfo) {
		//alert("calling make child for type " + widInfo.type + " and dom_id " + widInfo.dom_id);
		var that=this;
		var child;
		if (widInfo.type=="session") {
			child=sector67.makeSessionWidget(widInfo.dom_id, widInfo.id, '', 1);
		} else if (widInfo.type=="sessiontime") {
			child=sector67.makeSessionTimeWidget(widInfo.dom_id, widInfo.id, '', 1);
		}
		if (child!=null) that.addChild(child);
	};
	
	obj.addChild = function(child) {
		this.children.push(child);
		child.parent=this;
	};
	
	//given a jQuery element with the widget class,
	// returns info about it by checking and parsing the widget_info span inside it
	obj.getWidgetInfo = function (el) {
		var that=this;
		if (!el.hasClass("widget")) return {};
		var ret = {};
		var text = that.jQueryInElement("#widget_info",el).text();
		if (text=="") return {};
		
		var pieces = text.split("|");
		ret.type=pieces[0];
		ret.id=pieces[1];
		ret.dom_id=pieces[2];
		
		return ret;
	};
	
	obj.initFill = function () {
		//alert("init fill for " + this.dom_id);
		var that=this;
		
		if ((that.initHTML != null) && (that.initHTML != "")) {
			//alert("have init for " + this.dom_id);
			//just insert the html from here
			that.element.html(that.initHTML);
			that.findRefreshableElement();
			that.refresh(true);
		} else {
			//alert("do not have init for " + this.dom_id);
			//pull it from the server
			curParams=Object.create(that.pageParams);
			curParams["full"]="true";
			curParamString = $.param(curParams);
			
			sector67.ajaxGet(that.pageURL, curParamString,
				function (data) {
					that.element.html(data);
					that.findRefreshableElement();
					that.refresh(true);
				}
			);
		}
	};
	
	obj.refresh = function(initialRefresh) {
		var that=this;
		if (that.refreshableElement==null) return;
		
		curParams=Object.create(that.pageParams);
		if (that.editMode) {
			curParams["edit"]="true";
			refreshEvent="editRefresh";
		} else {
			curParams["edit"]="false";
			refreshEvent="pageRefresh";
		}
		//serialize params object
		curParamsString = $.param(curParams);
		sector67.ajaxGet(that.pageURL, curParamsString,
			function(data) {
				that.refreshableElement.html(data);
				//alert("about to find children");
				if(initialRefresh) that.findChildren();
				//alert("done with find children");
				
				that.eachChild(function () { this.findElement(); });
				//since we just filled with data from server, none of the sub widgets should be in edit mode
				that.eachChild(function () { this.editMode=false; });
				//alert("about to call from refresh");
				that.setPageEventListeners();
				if(!initialRefresh) that.eachChild(function () { this.setPageEventListeners(); }); //if initial refresh, then that.findChildren above will create children & call this
				if (that.editMode) that.element.addClass("editing_widget"); else that.element.removeClass("editing_widget");
				that.raiseEvent(refreshEvent);
			}
		);
	};
	
	obj.eachChild = function(func) {
		var that=this;
		for (child in that.children) {
			if((typeof that.children[child])!="function") {
				func.apply(that.children[child]);
				that.children[child].eachChild(func);
			}
		}
	}

	obj.jQueryInElement = function(query,el) {
		var that=this;
		
		if(el===undefined) el=that.element;
		var results = el.children(query);

		el.children().each(function (index, Element) {
			var child = $(this);
			if(!child.hasClass("widget")) results = results.add(that.jQueryInElement(query,child));
		});
		
		return results;
	};
	
	obj.setPageEventListeners = function() {
		var that=this;
		//alert("call into setPageEventListeners for " + that.dom_id);
		var el;
		//do children (recursively) first
		/*
		for (child in that.children) {
			if((typeof that.children[child])!="function") that.children[child].setPageEventListeners();
		}
		*/
		
		that.jQueryInElement("#save").bind('click', that.doSave(that));
		that.jQueryInElement("#cancel").bind('click', that.doCancel(that));
		that.jQueryInElement("#edit").bind('click', that.doEdit(that));
		
		//that.eachChild(function () {this.setPageEventListeners()});

		that.raiseEvent("setPageEventListeners");
	};
	
	obj.doEdit = function(that) {
		if (that==null) var that=this;
		
		return function() {
			that.eachChild(function() {
				if(this.editMode) { ((this.doCancel()) ());}
			});
			that.cachePage = that.refreshableElement.html();
			that.editMode=true;
			that.refresh();
			return false; //cancel default click action
		};
	};
	
	obj.doSave = function(that) {
		if (that==null) var that=this;
		return function() {
			//post a save...
			that.eachChild(function() {
				if(this.editMode) { ((this.doCancel()) ());}
			});
			curParams=Object.create(that.pageParams);
			curParams["save"]="true";
			curParamsString=$.param(curParams);
			//curParamsString = curParamsString + "&" + that.element.find("form").serialize();
			curParamsString = curParamsString + "&" + that.refreshableElement.serializeAnything();

			sector67.ajaxPost(that.pageURL, curParamsString,
				function(msg) {
					//if we made a new one, then the returned id should be the first part should be the new ID followed by a space
					var newId=msg.split(" ",1)[0];
					if (newId == parseInt(newId)) {
						that.setId(newId);
						that.raiseEvent('initialSave');
					} else {
						//alert(msg);
					}
					that.editMode=false;
					that.refresh();
				}
			);
		
			
			return false; //cancel default click action
		};
	};
	
	obj.setId = function (newId) {
		var that=this;
		that.id=newId;
		that.pageParams.id=newId;
	};
	
	obj.doCancel = function(that) {
		if (that==null) var that=this;
		return function() {
			that.editMode=false;
			if(that.cachePage!=null) {
				that.refreshableElement.html(that.cachePage); //load inner html with cached contents
				
				that.eachChild(function () {
					this.findElement();
					this.setPageEventListeners();
				});
				
				/*
				for (child in that.children) {
					if((typeof that.children[child])!="function") {
						that.children[child].findElement();
						// this gets called on children
						that.children[child].setPageEventListeners();
						//***also find children and make them do this?
					}
				}
				*/
				
				that.setPageEventListeners();
				that.element.removeClass("editing_widget");
			} else {
				that.refresh();
			}
			return false; //cancel default click action
		};
	};
	
	
	obj.addListener = function(event, func) {
		var that=this;
		if(!that.eventsMap[event]) that.eventsMap[event]=new Array();
		that.eventsMap[event].push(func);
	};
	
	//adds a function to the click event of an element inside the widget (and not in the sub widget)
	// give it the id of the element to attach the event to, and a function.  context
	// will be of the widget (this will be reference to widget object)
	obj.addClickEvent = function(dom_id, func) {
		var that=this;
		that.addListener("setPageEventListeners", function() {
			var that=this;
			//var test = that.element.children("#none");
			that.jQueryInElement("#" + dom_id).bind('click', function() { func.apply(that); });
		});
	};
	
  
	//calls an event of this widget
	obj.raiseEvent = function(event) {
		var that=this;
		var funcNum;
		var func;
		for (funcNum in that.eventsMap[event]) {
			func = that.eventsMap[event][funcNum];
			if (typeof func == 'function') {
				func.apply(that,arguments); //call func with first param of that, and next params as whatever else got passed to raiseEvent
			}
		}
	};
	
	obj.applyToChildren = function(func) {
		var that=this;
		var args = arguments;
		throwaway = arg.shift; //remove func from arguments array
		for (childNum in that.children) {
			child = that.children[childNum];
			alert("child type: " + typeof child + " NOT YET IMPLEMENTED");
			//func.apply(child, args);
		}
	};
	
	
	//actual constructor
	obj.init = function(dom_id,id,pageURL,pageParams,editMode,suppressRefresh) {
		var that=this;

		that.dom_id=dom_id;
		
		that.element=$("#"+dom_id);
		
		that.children = new Array();
		
		if(editMode) {
			that.editMode=editMode;
		} else {
			that.editMode=false;
		}

		
		that.pageURL=pageURL;
		that.pageParams=pageParams;
		if(!that.pageParams) that.pageParams = new Object();
		that.pageParams.elementId=that.dom_id;
		that.setId(id);
		
		if(!suppressRefresh) {
			that.initFill();
		} else {
			that.findRefreshableElement();

			that.setPageEventListeners();
			that.findChildren();
		}
	};
	
	return obj;
} ();


// *** ClassWidget **********************************************************

sector67.ClassWidget = function () {
	var obj = Object.create(sector67.EditableWidget);
	
	var super_init=obj.init;
	//obj.initHTML = "<div id='refreshable'></div><p>this text doesn't refresh</p>";
	obj.type="class"
	
	obj.init = function(dom_id,class_id,editMode,suppressRefresh) {
		var that=this;
		that.class_id=class_id;
		super_init.call(that,dom_id,class_id,"widgets/widClass.php",{},editMode,suppressRefresh);
	}
	
	obj.eventsMap = Object.create(obj.eventsMap);
	
	obj.addClickEvent("deactivate", function() {
		var that=this;
		
		if(confirm("Are you sure you want to deactivate this class?")) {
			curParams=Object.create(that.pageParams);
			curParams["deactivate"]="true";
			curParamsString=$.param(curParams);

			sector67.ajaxPost(that.pageURL, curParamsString,
				function(msg) {
					//alert(msg);
					that.refresh();
				}
			);
		}

		return false; //cancel default click action
	});
	
	obj.addClickEvent("activate", function() {
		var that=this;
		
		if(confirm("Are you sure you want to reactivate this class?")) {	
			curParams=Object.create(that.pageParams);
			curParams["activate"]="true";
			curParamsString=$.param(curParams);

			sector67.ajaxPost(that.pageURL, curParamsString,
				function(msg) {
					//alert("deactivate return: " + msg);
					//alert(msg);
					that.refresh();
				}
			);
		}

		return false; //cancel default click action
	});

	obj.addClickEvent("add_session", function() {
		var that=this;
		
		if(typeof(new_session_count)=="undefined") new_session_count=0;
		new_session_count += 1;
		dom_id="new_session_" + new_session_count;
		that.jQueryInElement("#session_table").append("<tr id='" + dom_id + "' class='widget'></tr>");
		child=sector67.makeSessionWidget(dom_id,0,1);
		that.addChild(child);
		child.pageParams["class_id"]=that.id;
		that.jQueryInElement("#session_table").css("display","block");
		
		return false; //cancel default click action
	});
	
	obj.addClickEvent("removeInterested", function() {
		var that=this;
		
		curParams=Object.create(that.pageParams);
		curParams["removeInterested"]="true";
		curParamsString=$.param(curParams);

		sector67.ajaxPost(that.pageURL, curParamsString,
			function(msg) {
				that.refresh();
			}
		);
	});
	
	obj.addClickEvent("addInterested", function() {
		var that=this;
		
		curParams=Object.create(that.pageParams);
		curParams["addInterested"]="true";
		curParamsString=$.param(curParams);

		sector67.ajaxPost(that.pageURL, curParamsString,
			function(msg) {
				that.refresh();
			}
		);
	});
	
	obj.addClickEvent("showPastSessions", function() {
		var that=this;
		
		that.jQueryInElement("#showPastSessions").html("");
		
		curParams=Object.create(that.pageParams);
		curParams["showPastSessions"]="true";
		curParamsString=$.param(curParams);

		sector67.ajaxPost(that.pageURL, curParamsString,
			function(msg) {
				that.jQueryInElement("#pastClasses").html(msg);
				that.refresh();
			}
		);
	});
	
	return obj;
} ();

sector67.makeClassWidget = function(dom_id,class_id,editMode,suppressRefresh) {
	var that = Object.create(sector67.ClassWidget);
	that.init(dom_id,class_id,editMode,suppressRefresh);
	return that;
}

// *** SessionWidget **********************************************************

sector67.SessionWidget = function () {
	var obj = Object.create(sector67.EditableWidget);
	
	var super_init=obj.init;
	obj.initHTML="";
	obj.type="session"
	
	obj.init = function(dom_id,session_id,editMode,suppressRefresh) {
		var that=this;
		that.session_id=session_id;
		super_init.call(that, dom_id,session_id,"widgets/widSession.php",{},editMode,suppressRefresh);
	}
	
	obj.eventsMap = Object.create(obj.eventsMap);

	obj.addClickEvent("cancel_session", function() {
		var that=this;
		
		if(confirm("Are you sure you want to cancel this session?")) {
			//cancel the session
			curParams=Object.create(that.pageParams);
			curParams["cancel"]="true";
			curParamsString=$.param(curParams);
			//curParamsString = curParamsString + "&" + that.refreshableElement.serializeAnything();

			sector67.ajaxPost(that.pageURL, curParamsString,
				function(msg) {
					alert(msg);
					that.refreshableElement.html("");
				}
			);
		
			
			return false; //cancel default click action
		}
	});
	
	obj.addClickEvent("add_time", function() {
		var that=this;
		
		if(typeof(new_time_count)=="undefined") new_time_count=0;
		new_time_count += 1;
		dom_id="new_time_" + new_time_count;
		that.jQueryInElement("#time_table").append("<div id='" + dom_id + "' class='widget'></tr>");
		child=sector67.makeSessionTimeWidget(dom_id,0,1);
		that.addChild(child);
		child.pageParams["session_id"]=that.id;
		return false; //cancel default click action
	});
	
	obj.addClickEvent("register", function() {
		//alert("sub register");
		var that=this;
		
		curParams=Object.create(that.pageParams);
		curParams["register"]="true";
		curParamsString=$.param(curParams);
		//curParamsString = curParamsString + "&" + that.refreshableElement.serializeAnything();

		sector67.ajaxPost(that.pageURL, curParamsString,
			function(msg) {
				//alert("register return: " + msg);
				//alert(msg);
				that.refresh();
			}
		);
		return false; //cancel default click action
	});
	
	//alert("adding drop function");
	obj.addClickEvent("drop", function() {
		//alert("sub drop");
		var that=this;
		
		curParams=Object.create(that.pageParams);
		curParams["drop"]="true";
		curParamsString=$.param(curParams);
		//curParamsString = curParamsString + "&" + that.refreshableElement.serializeAnything();

		sector67.ajaxPost(that.pageURL, curParamsString,
			function(msg) {
				//alert("drop return: " + msg);
				//alert(msg);
				that.refresh();
			}
		);
		return false; //cancel default click action
	});
	
	obj.addListener("initialSave", function() {
		var that=this;
		that.jQueryInElement("#add_time").css('display','block');
	});
	
	return obj;
} ();

sector67.makeSessionWidget = function(dom_id,session_id,editMode,suppressRefresh) {
	var that = Object.create(sector67.SessionWidget);
	that.init(dom_id,session_id,editMode,suppressRefresh);
	return that;
}

//*** SessionTimeWidget ****************************
sector67.SessionTimeWidget = function () {
	var obj = Object.create(sector67.EditableWidget);
	
	var super_init=obj.init;
	obj.initHTML="";
	obj.type="sessiontime";
	
	obj.init = function(dom_id,time_id,editMode,suppressRefresh) {
		var that=this;
		that.time_id=time_id;
		super_init.call(that, dom_id,time_id,"widgets/widSessionTime.php",{"time_id" : time_id},editMode,suppressRefresh);
	}
	
	obj.eventsMap = Object.create(obj.eventsMap);

	obj.addClickEvent("delete_time", function() {
		var that=this;
		//delete the session time
		curParams=Object.create(that.pageParams);
		curParams["cancel"]="true";
		curParamsString=$.param(curParams);
	
		sector67.ajaxPost(that.pageURL, curParamsString,
			function(msg) {
				alert(msg);
				that.refreshableElement.html("");
				that.element.removeClass('editing_widget');
			}
		);
		return false; //cancel default click action
	});
	
	return obj;
} ();

sector67.makeSessionTimeWidget = function(dom_id,time_id,editMode,suppressRefresh) {
	var that = Object.create(sector67.SessionTimeWidget);
	that.init(dom_id,time_id,editMode,suppressRefresh);
	return that;
}


//*** User ****************************
sector67.UserWidget = function () {
	var obj = Object.create(sector67.EditableWidget);
	
	var super_init=obj.init;
	obj.initHTML="";
	obj.type="user"
	
	obj.init = function(dom_id,user_id,editMode,suppressRefresh) {
		var that=this;
		that.user_id=user_id;
		super_init.call(that, dom_id,user_id,"widgets/widUser.php",{"user_id" : user_id},editMode,suppressRefresh);
	}
	
	obj.eventsMap = Object.create(obj.eventsMap);
	
	obj.addClickEvent("add_new_perm", function () {
		var that=this;
		var new_perm_id=that.jQueryInElement("[name=new_perm]").val();
		//alert("add new permission with id " + new_perm_id);

		curParams=Object.create(that.pageParams);
		curParams["add_permission"]="true";
		curParams["permission_id"]=new_perm_id;
		curParamsString=$.param(curParams);
	
		sector67.ajaxPost(that.pageURL, curParamsString,
			function(msg) {
				//alert(msg);
				that.refresh();
				//that.refreshableElement.html("");
				//that.element.removeClass('editing_widget');
			}
		);
		return false; //cancel default click action
	});

	obj.addListener("setPageEventListeners", function() {
		//alert("add del perm listeners");
		var that=this;
		var pre="del_perm_";
		
		that.jQueryInElement("[id^=" + pre + "]").each(function () {
			var el = $(this);
			var dom_id = el.attr('id');
			perm_id = dom_id.substring(pre.length);
			
			makeDelPermFunc = function(perm_id,that) {
				return function () {
					(function () {
						var that=this;
						//alert('del_perm called for ' + that.id + ' and perm_id ' + perm_id);
						
						//delete the session time
						curParams=Object.create(that.pageParams);
						curParams["delete_permission"]="true";
						curParams["permission_id"]=perm_id;
						curParamsString=$.param(curParams);
					
						sector67.ajaxPost(that.pageURL, curParamsString,
							function(msg) {
								//alert(msg);
								that.refresh();
								//that.refreshableElement.html("");
								//that.element.removeClass('editing_widget');
							}
						);
						return false; //cancel default click action
					}).apply(that);
				};
			};
			//func = makeDelPermFunc(perm_id);
			
			//el.bind('click', function() { makeDelPermFunc(perm_id).apply(that); });
			el.bind('click', makeDelPermFunc(perm_id, that));
		});
	});
	
	return obj;
} ();

sector67.makeUserWidget = function(dom_id,user_id,editMode,suppressRefresh) {
	var that = Object.create(sector67.UserWidget);
	that.init(dom_id,user_id,editMode,suppressRefresh);
	return that;
}

