(function($){

var dash = window.dash = function(a) {
	// If the context is global, return a new object
	if ( window == this || !this.init )
		return new dash(a);
	
	return this.init(a);
};

window.dash = dash;

dash.fn = dash.prototype = {
	init: function(a)
	{
		a = a || document;
		
		Array.prototype.push.apply( this, a );
		return this
	}
}

dash.extend = $.extend;

dash.extend({
	forceHashURL: true,
		
	get:  function( call, params, callback ) { dash.makeRequest( call, params, callback, "GET" ) },
	post: function( call, params, callback ) { dash.makeRequest( call, params, callback, "POST" ) },
		
	makeRequest: function( call, params, callback, type )
	{
		if ( $.isFunction(params) )
		{
			callback = params;
			params = null;
		}
		
		params = params || null;
		
		if ( typeof call == "string" )
		{
			var info = call.split(".", 2);
			
			controller = info[0] || "home";
			method     = info[1] || "";
			
			var url = "/" + controller + "/" + method;
			
			$.ajax({
				url: url, 
				
				type: type,
				data: params,
				dataType: "json",
				
				beforeSend: function (request) {
				  request.setRequestHeader( "x-requested-response", "json" );
				},
				
				error: dash.onRequestError,
				success: function( data )
				{
					if ( $.isFunction(callback) )
					{
						alert("calling callback");
						callback.apply(this, arguments);
					}
					
					dash.onRequestComplete.apply(this, arguments);
				}
			});
		}
	},
	
	call: function( call )
	{
		var info = call.split("."), args = arguments;
		
		Array.prototype.shift.apply(args);
			
		if ( typeof info[1] == "undefined" )
			info[1] = "";
		
		if ( ! dash[info[0]] )
		{
			$.ajax({
				url: "/js/dash."+info[0]+".js", 
				
				dataType: "script",
				
				success: function()
				{
					dash.execChild(info[0],info[1],args);
				}
			});
			
			return;
		}
		
		dash.execChild(info[0],info[1],args);
	},
	
	require: function( name )
	{
		$.ajax({
			url: "/js/"+name+".js", 
			
			dataType: "script",
			async: false
		});
	},
	
	execChild: function( namespace, method, args )
	{
		dash[namespace][method].apply(this,args);
	},
	
	reload: function()
	{
		var hash = dash.history.getCurrent();
		
		return dash.onHistoryChange( hash, historyStorage.get(hash) );
	},
	
	fullReload: function()
	{
		var hash = dash.history.getCurrent();
		
		document.location = "/#" + hash;
		
		if ( document.location.reload )
			document.location.reload()
		else
			window.location.reload()
	},
	
	onRequestError: function( request, status, errorThrown )
	{
		settings = this;
		
		if ( request.status == 401 )
			alert( "Insufficient permissions for " + settings.url );
		
		if ( request.status == 404 )
			alert( "No page found at " + settings.url );
	},
	
	onRequestComplete: function( data )
	{
		if ( data.status == "ok" && data.response )
		{
			$("body").attr("id", data.namespace || "home")
			
			if ( data.response > "" && data.response !== true )
				$(".main_content").html( data.response );
			
			if ( data.logged_in == false )
				$("body").removeClass("logged_in").find(".user_container").empty();
			else
				$("body").addClass("logged_in");
				
			if ( data.user_status )
				$(".user_container").html( data.user_status );
		}
	},
	
	onHistoryChange: function( location, data )
	{
		if ( dash.history.firstLoad == true )
		{
			if ( dash.forceHashURL == true )
			{
				currentLocation = dash.checkLocation().toString().split("#")[0];
				
				parts = currentLocation.toString().split("/", 4);
				
				path   = currentLocation.substring( parts[0].length + parts[1].length + parts[2].length + 3 );
				
				if ( path > "" )
					dash.redirect("/#/"+path);
			}
			
			if ( location == "/" || location == "" )
				return;
		}
		
		call = location.substring(1);
		call = call.replace( /\//g, "." );
		
		dash.history.firstLoad = false;
			
		dash.get( call, data );
	},
	
	onAnchorClicked: function( event )
	{
		var href = $(this).attr("href");
		
		if ( href.match(/^(https?:\/\/|ftp:\/\/)/) )
			return true; // external link
		
		if ( href.substring(0,1) == "#" )
			href = href.substring(1);
		
		if ( href.substring(0,1) == "/" )
			href = href.substring(1);
		
		dash.history.add("/"+href);
		dash.get(href);
		
		return false;
	},
	
	checkLocation: function()
	{
		return window.location;
	},
	
	redirect: function( url )
	{
		document.location = url;
	},
	
	history: {}
});

$.extend( dash.history, {
	firstLoad: true,
		
	add: function( location, data )
	{
		dhtmlHistory.add(location, data);
	},
	
	getCurrent: function()
	{
		return dhtmlHistory.getCurrentLocation();
	}
});
		
window.dhtmlHistory.create();

dash.require("jquery/livequery");

$(function() {
	$("a").livequery("click", dash.onAnchorClicked);
	dhtmlHistory.initialize();
	dhtmlHistory.fireOnNewListener = true;
	dhtmlHistory.addListener(dash.onHistoryChange);
});

		
})(jQuery);
