/**
 * Global state shared within the app for scene transitions.
 
Copyright 2009 Palm, Inc.  All rights reserved.

*/
var State =
{
	dashboard: new Weave.Models.Model(),
	listOfLists: new Weave.Models.Model(),
	taskList: null,
	task: null, 
};

var AppAssistant = Class.create(
{
	initialize: function ()
	{
	    Mojo.Log.info('AppAssistant::initialize %s', curTicks());
		
		//if (navigator.userAgent.indexOf('Safari') != -1) window.resizeBy(320 - window.innerWidth, 432 - window.innerHeight);
	},

	/**
	 * Setup the system by adding two interfaces:
	 *  main	- handles general launch and relaunch
	 *  details	- (re)launch the app pointing at a specific taskList and task.
	 */
	setup: function()
	{
	    Mojo.Log.info('AppAssistant::setup');
		
		Weave.System.Activator.addIndex('default', 'index-default');
		Weave.System.Activator.addIndex('dashboard', 'index-dashboard');
		Weave.System.Activator.addInterface({ name: 'main', stagename: 'default' },
		{
			start: function(stage)
			{
				(function()
				{
					stage.controller.pushScene('tasklists');
				}).defer();
			},
			
			restart: function(stage)
			{
				stage.controller.activate();
			}
		});
		Weave.System.Activator.addInterface({ name: 'details', stagename: 'default' },
		{
			show: function(args, stage)
			{
				stage._showTaskAndTaskList(args);
			}
		});
		Weave.System.Activator.addInterface({ name: 'dashboard', stagename: null },
		{
			notify: function(args)
			{
				State.dashboard.update(self, args);
			}
		});
		
		// Delay starting the dashboard up so we can spend time getting the front page up
		this._startDashboard.bind(this).delay(3);
	},
	
	cleanup: function()
	{
		Mojo.Log.info("AppAssistant::cleanup");
		
		State.dashboard.removeUpdateListener(this);
	},
	
	handleLaunch: function(params)
	{
		Mojo.Log.info("AppAssistant::handleLaunch %j", params);
		
		Weave.System.Activator.run(params);
	},
	
	/**
	 * Start the dashboard up (creating a model if it doesnt already exist) and watch the system
	 * for changes which are then propogated to the model (and on to all observers).
	 */
	_startDashboard: function()
	{
		var self = this;
		this._dashboardreq = new Weave.Services.ServiceObserver(this, "palm://com.palm.tasks/appInit", { type: 'dashboard' }, function(status, response)
		{
			State.dashboard.update(self, response.dashboard.notify, true);
		});
		// Watch the dashboard for changes to the 'dueItemCount'.  We use this this to open and close the dashboard window.
		var first = true;
		State.dashboard.addUpdateListener(this, function(model, diff)
		{
			// Only update the dashboard if the something changes or if this is the very first notify since reboot
			if (model.lastNotifyDate == 0 || (!first && ('dueItemCount' in diff || 'taskName' in diff || 'taskListName' in diff)))
			{
				if (model.dueItemCount) 
				{
					Weave.System.Activator.open('dashboard');
				}
				else 
				{
					Weave.System.Activator.close('dashboard');
				}
			}
			first = false;
		});
	},
});

/**
 * Default Stage Manager.
 * We enhance it by adding the Help system (so all scenes share it).
 */
var DefaultStageAssistant = Class.create(
{
	setup: function()
	{
		Mojo.Log.info("StageAssistant::setup");
		
		Weave.Utilities.AppMenu.setDefault(new Weave.Utilities.AppMenu(this).addEdit().addHelp('http://help.palm.com/tasks/index.html'));
	},
	
	cleanup: function()
	{
		Mojo.Log.info("StageAssistant::cleanup");
	},

	/**
	 * Open the app at the place indicated by the taskId and taskListId.
	 * We try to do this by changing the minimum number of scenes.
	 * 
	 * @param {Object} arg
	 */
	_showTaskAndTaskList: function(arg)
	{
		Mojo.Log.info("_showTaskAndTaskList %j", arg);
		var ctrl = this.controller;
		
		var top = ctrl.topScene();
		if (!arg.taskId || !arg.taskListId) 
		{
			// If no specific task or list, we just go the main view.
			if (!top) 
			{
				ctrl.pushScene('tasklists');
			}
			else 
			{
				ctrl.popScenesTo('tasklists');
			}
		}
		else 
		{
			// Push the specific task and list.
			if (top) 
			{
				if (top.sceneName == 'tasks' && State.taskList && State.taskList.id == arg.taskListId && !arg.taskId) 
				{
					arg.taskListId = null;
				}
				else if (top.sceneName == 'task' && State.task && State.task.id == arg.taskId) 
				{
					arg.taskListId = null;
					arg.taskId = null;
				}
			}
			if (arg.taskListId) 
			{
				State.taskList = new TaskList({ id: arg.taskListId }).load(this, function()
				{
					State.task = new Task({ id: arg.taskId }).load(this, function()
					{
						if (!top) 
						{
							ctrl.pushScene('tasklists');
						}
						else 
						{
							ctrl.popScenesTo('tasklists');
						}
						ctrl.pushScene('tasks');
						ctrl.pushScene('task');
					});
				});
			}
			else if (arg.taskId)
			{
				State.task = new Task({ id: arg.taskId }).load(this, function()
				{
					ctrl.pushScene('task');
				});
			}
		}
		
		ctrl.activate();
	}
});

/**
 * The Dashboard assistant - just pushes the dashboard scene.
 */
var DashboardStageAssistant = Class.create(
{
	initialize: function()
	{
	},
	
	setup: function()
	{		
		this.controller.pushScene('dashboard');
	},
	
	cleanup: function()
	{
	},
});

// ------------------------------- This needs to go away -----------------------------------

var curTicks = function()
{
	var n = new Date();
	var t = n.getTime() - curTicks.last.getTime();
	curTicks.last = n;
    return t + "ms";
};
curTicks.last = new Date();
