
if (!Array.prototype.forEach) {
  Array.prototype.forEach = function(fn){
	for ( var i = 0; i < this.length; i++ ) {
	  fn( this[i], i, this );
	}
  };
}

if (!Array.prototype.reduce) {
  Array.prototype.reduce = function(fun /*, initial*/) {
	var len = this.length;
	if (typeof fun != "function") {
	  throw new TypeError();
	}

	// no value to return if no initial value and an empty array
	if (len === 0 && arguments.length === 1) {
	  throw new TypeError();
  }

	var i = 0;
	if (arguments.length >= 2) {
	  var rv = arguments[1];
	}
	else   {
	  do {
		if (i in this) {
		  rv = this[i++];
		  break;
		}

		// if array contains no values, no initial value to return
		if (++i >= len) {
		  throw new TypeError();
	  }
	  }
	  while (true);
	}

	for (; i < len; i++) {
		if (i in this) {
			rv = fun.call(null, rv, this[i], i, this);
		}
	}

	return rv;
  };
}


iphjs = {};
iphjs.plugins = {};

iphjs.Event = function () {
	this.eventHandlers = [];
};

iphjs.Event.prototype.addHandler = function(eventHandler) {
	this.eventHandlers.push(eventHandler);
};

iphjs.Event.prototype.raise = function() {
	for(var i = 0; i < this.eventHandlers.length; i++) {
		this.eventHandlers[i].apply(this,arguments);
	}
};

iphjs.Base = function() {
	var meta ,
			tabs,
			onTabSwitch = new iphjs.Event(),
			onPluginsLoaded = new iphjs.Event();

	function trace(msg) {
		if(window.console){
			window.console.log(msg);
		}
	}

	function formJSON(f) {
		return $(f).formToArray().reduce(
			function(s,n) {
				s[n.name] = n.value;
				return s;
			},{});
	}

	function loader(scripts,finalfn) {
		var s = scripts.shift();
		if (s) {
			$.getScript(s,function() {
				loader(scripts,finalfn);
			});
		} else {
			finalfn();
		}
	}

	function locator() {
		$.getJSON("/locator.json",function(m) {
			var scripts = [];
			meta = m;

			if  (meta.accountServer) {
				scripts.push("/js/accounts.js");
			}

			for (p = 0; p < meta.plugins.length;p++) {
				if (meta.plugins[p] == "feeds") {
					scripts.push("/js/google.js");
				}
				if (meta.plugins[p] == "tables") {
					scripts.push("/js/tables.js");
				}
				if (meta.plugins[p] == "chat") {
					scripts.push("/js/chat.js");
				}
			}

			scripts.push("/site.js");

			loader(scripts,function() {
				initDialog();
				onPluginsLoaded.raise(meta);
			});
		});
	}

	function initDialog() {
		$('#dialog').dialog({
			bgiframe: true,
			autoOpen:false,
			modal: true,
			buttons: {
				Ok: function() {
					$(this).dialog('close');
				}
			}
		});
	}

	function template(tmpl,data) {
		return TrimPath.processDOMTemplate(tmpl, data);
	}

	function msg(m) {
		var d = $('#dialog');
		d.html(m);
		d.dialog('open');
	}

	function doService(url,params,callback) {
		var me = this,
		p = $.param(params),
		u = (p.length === 0) ? url : url + "&" + p;

		trace("service: "+u);

		$.getJSON(u,function(data) {
			if (data.ERR > 0) {
				trace(data.MSG);
			} else {
				callback(data);
			}
		});
	}

	/* this is the entry point, called by jQuery when the DOM is ready */
	$(function() {
		locator();
		tabs = $("#tab-container").tabs();
		$('#tab-container').bind('tabsshow', function(event, ui) {
			var selected = $(ui.tab).text().toLowerCase();
			onTabSwitch.raise(selected);
		});
	});

	return {
		formJSON:formJSON,
		getAccountServer: function() {
			return meta.accountServer;
		},
		doService:doService,
		trace:trace,
		onTabSwitch:onTabSwitch,
		onPluginsLoaded:onPluginsLoaded,
		tabs: function() { return tabs; },
		template:template,
		msg:msg
	};

}();
