/* Copyright 2009 Palm, Inc.  All rights reserved. */

var TasklistsAssistant = Class.create(
{	
    initialize: function()
	{
    },
    
    setup: function()
	{
        Mojo.Log.info('TasklistsAssistant::setup %s', curTicks());
     		
        // Whole scene
        this.sceneElement = this.controller.get('tasks-groups');

        this.controller.setupWidget('groupList', 
		{
            itemTemplate: 'tasklists/tasklist-entry',
            swipeToDelete: true,
            reorderable: true,
            formatters: {
                dummy: this.formatItem.bind(this)
            },
			preventDeleteProperty: 'nodelete',
            itemsCallback: this.itemsCallback.bind(this),
        }, {});
        
        // Set up a command menu
        this.controller.setupWidget(Mojo.Menu.commandMenu, 
		{
            menuClass: 'task-lists'
        },
		{
        	items:
			[{
                icon: "new-list-button",
                command: 'add'
            }]
        });
        
        this.listElement = this.controller.get('groupList');
        this.listElement.observe(Mojo.Event.listTap, this.handleTap.bindAsEventListener(this));
        this.listElement.observe(Mojo.Event.listDelete, this.handleDelete.bindAsEventListener(this));
        this.listElement.observe(Mojo.Event.listReorder, this.handleReorder.bindAsEventListener(this));
        
        // Filter
        this.controller.setupWidget('filterField');
        this.filterField = this.controller.get('filterField');
        this.filterField.observe(Mojo.Event.filter, this.handleFilter.bindAsEventListener(this));
        
        // All tasks
        this.controller.listen('alltasks', Mojo.Event.tap, this.handleAllTasksTap.bindAsEventListener(this));
		this._allTaskListCookie = new Mojo.Model.Cookie("alltasklist");
		var cookie = this._allTaskListCookie.get();
		cookie = cookie ? cookie.split(":") : [];
		this._allTaskList = { name: $L('All tasks'), id: 'alltasks', show: cookie[0] ? cookie[0] : "all", order: cookie[1] ? cookie[1] : "position" };
		
		// Menus
		Weave.Utilities.AppMenu.useDefault(this);
		
        // Watch the total due count (in the dashboard model)
        this._watchTotalDueCount();
		
		// If we have a State.taskList then set it to the current one
		if (State.taskList)
		{
			this._setCurrentList(State.taskList);
		}
    },
	
	cleanup: function()
	{
	    Mojo.Log.info('TasklistsAssistant::cleanup');
		if (State.taskList)
		{
			State.taskList.removeUpdateListener(this);
		}
		State.listOfLists.removeUpdateListener(this);
		State.dashboard.removeUpdateListener(this);
	},
  
    handleFilter: function(event)
	{
        // Prevent update the first time
        if (this.filterString || event.filterString) 
		{
            this.filterString = event.filterString;
            
            if (this.filterString) 
			{
                this.sceneElement.addClassName('filtering');
                this.controller.select('.palm-filterfield-spacer')[0].addClassName('filtering');
            }
            else 
			{
                this.sceneElement.removeClassName('filtering');
				this.controller.select('.palm-filterfield-spacer')[0].removeClassName('filtering');
            }
            this.listElement.mojo.reloadAll();
        }
    },
    
    handleTap: function(event)
	{
        var item = event.item;
        if (item)
		{
            this._openList(item);
            Event.stop(event);
        }
    },
    
    handleAllTasksTap: function(event)
	{
        this._openList(this._allTaskList);
        Event.stop(event);
    },
	
	_setCurrentList: function(item)
	{
		if (State.taskList)
		{
			State.taskList.removeUpdateListener(this);
		}
		Mojo.Log.info("Opening list %j", item);
		State.taskList = item;
		var self = this;
		State.taskList.addUpdateListener(this, function(model, diff)
		{
			Mojo.Log.info("Current list update %j %j", model, diff);
			if (!model.id) 
			{
				// If we don't have an id, we weren't save or were deleted - remove us
				var idx = self.listElement.mojo.getItemIndexByProperty(diff.id, 'id');
				if (idx !== undefined) 
				{
					self.listElement.mojo.noticeRemovedItems(idx, 1);
				}
			}
			else 
			{
				if ('id' in diff) 
				{
					// If original item didnt have an id, and we now do, insert it at the top
					self.listElement.mojo.insertItemsAt(0, [ model ]);
					// If we dont know the dueItem count, we have to refresh the item from the DB
					if (model.dueItemCount == null)
					{
						self.listElement.mojo.invalidateItems(0, 1);
					}
				}
				else 
				{
					var idx = self.listElement.mojo.getItemIndexByProperty(model.id, 'id');
					// If we dont know the dueItem count, we have to refresh the item from the DB
					if (model.dueItemCount == null) 
					{
						self.listElement.mojo.invalidateItems(idx, 1);
					}
					// Otherwise, just update it
					else 
					{
						self.listElement.mojo.noticeUpdatedItems(idx, [ model ]);
					}
				}
				// We save the alltasks show state locally - we have no where else to actually persist it
				if (TaskList.isAllTasks(model))
				{
					self._allTaskList.show = model.show;
					self._allTaskList.order = model.order;
					self._allTaskListCookie.put(model.show + ":" + model.order);
				}
			}
		});
	},
	
	_openList: function(item)
	{
		this._setCurrentList(new TaskList(item));
		this.controller.stageController.pushScene('tasks');
	},
    
    handleDelete: function(event)
	{
		new TaskList(event.item).remove(this);
    },
    
    handleReorder: function(event)
	{
        Mojo.Log.info('Moving from %s to %s', event.fromIndex, event.toIndex);
		new TaskList(event.item).move(this, this.filterString, event.toIndex, event.fromIndex);
    },
    
    itemsCallback: function(widget, offset, length)
	{
		var self = this;
		TaskList.getAll(this, this.filterString, offset, length, true, function(status, list, count)
		{
            if (self.filterString)
			{
				self.filterField.mojo.setCount(count);
				// If we're filtering a list, put the focus back at the top
				if (offset == 0) 
				{
					widget.mojo.revealItem(0);
				}
			}
			
			Mojo.Log.info("Updating %d %j %d", offset, list, count)
	        widget.mojo.updateItemsAndTotalLength(offset, list, count);
        });
    },
    
    // Weird actually we have a dummy propery that we don't use
    // Instead we simply update the existing item.
    formatItem: function(dummy, item)
	{
		var dname = TaskList.getNameWithDefault(item).escapeHTML();
		if (this.filterString) 
        {
            item.nameFormatted = dname.replace(new RegExp('(' + Weave.Utilities.RegExp.escape(this.filterString) + ')', 'gi'), '<span class="list-highlight">$1</span>');
        }
		else
		{
			item.nameFormatted = dname;
		}
        item.dueItemCountFormatted = item.dueItemCount;
		item.classFormatted = '';
        
        if (TaskList.isDefault(item))
		{
			// Fixup the default list name.
			// We only care because if we don't do this then typedown search on list names will fail to find it.
			if (item.name != dname)
			{
				item.name = dname;
				new TaskList(item).save(this);
			}
            item.classFormatted += "unfiled";
        }
		// Special items cannot be deleted
		if (TaskList.isSpecial(item))
		{
			item.nodelete = true;
		}
        if (item.dueItemCount | 0) 
		{
            item.classFormatted += " due";
        }
		item.eas = TaskList.isEAS(item) ? 'block' : 'none';
		item.unreadTagRotation = Math.round(Math.random()*10)-5;
	},
 
    handleCommand: function(event)
	{
        // Handle the add menu item
        if (event.type == Mojo.Event.command && event.command == 'add') 
		{
			Mojo.Log.info("add");
			this._openList(
			{
				position: new Date().getTime()
			});
			Event.stop(event);
		}
    },

	_watchTotalDueCount: function()
	{
		var self = this;
		function doUpdate(model)
		{
			Mojo.Log.info("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %j", model);
		    if (model.dueItemCount) 
			{
		        self.controller.get('itemAllDueItemCount').update(model.dueItemCount);
		        self.controller.get('itemAll').addClassName("due");
		    }
		    else 
			{
		        self.controller.get('itemAll').removeClassName("due");
		    }
			// When dashboard changes, update the list-of-lists
			if (self.listElement.mojo) 
			{
				self.listElement.mojo.reloadAll();
			}
		};
		State.dashboard.addUpdateListener(this, doUpdate);
		doUpdate(State.dashboard);
		
		// Watch list of lists and reload if necessary
		State.listOfLists.addUpdateListener(this, function()
		{
			self.listElement.mojo.reloadAll();
		});
	},
});