/*
This file is part of Ext JS 3.4

Copyright (c) 2011-2013 Sencha Inc

Contact:  http://www.sencha.com/contact

GNU General Public License Usage
This file may be used under the terms of the GNU General Public License version 3.0 as
published by the Free Software Foundation and appearing in the file LICENSE included in the
packaging of this file.

Please review the following information to ensure the GNU General Public License version 3.0
requirements will be met: http://www.gnu.org/copyleft/gpl.html.

If you are unsure which license is appropriate for your use, please contact the sales department
at http://www.sencha.com/contact.

Build date: 2013-04-03 15:07:25
*/
Ext.onReady(function(){
    Ext.QuickTips.init();

    var xg = Ext.grid;
    // turn off default shadows which look funky in air
    xg.GridEditor.prototype.shadow = false;
    
    var conn = Ext.data.SqlDB.getInstance();
	conn.open('tasks.db');
    
    // the main grid store
    var taskStore = new TaskStore(conn);
    
    // Category store shared by category combos
    var catStore = new CategoryStore();
    
	taskStore.load({
		callback: function(){
			// first time?
			if(taskStore.getCount() < 1){
				Ext.Msg.confirm('Create Tasks?', 'Your database is currently empty. Would you like to insert some demo data?', 
					function(btn){
						if(btn == 'yes'){
							loadDemoTasks(taskStore);	
						}
						catStore.init(taskStore);
					});
			}else{
				catStore.init(taskStore);
			}
		}
	});

    // custom event to notify when a new category is available
    taskStore.on('newcategory', catStore.addCategory, catStore);

    // set of event handlers shared by combos to allow them to share
    // the same local store
    var comboEvents = {
        focus: function(){
            this.bindStore(catStore);
        },
        blur: function(c){
            catStore.purgeListeners();
        }
    }

    var completeColumn = new CompleteColumn();

    // custom template for the grid header
    var headerTpl = new Ext.Template(
        '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
        '<thead><tr class="x-grid3-hd-row">{cells}</tr></thead>',
        '<tbody><tr class="new-task-row">',
            '<td><div id="new-task-icon"></div></td>',
            '<td><div class="x-small-editor" id="new-task-title"></div></td>',
            '<td><div class="x-small-editor" id="new-task-cat"></div></td>',
            '<td><div class="x-small-editor" id="new-task-due"></div></td>',
        '</tr></tbody>',
        "</table>"
    );

    var selections = new Ext.grid.RowSelectionModel();

    // The main grid in all its configuration option glory
    var grid = new xg.EditorGridPanel({
        id:'tasks-grid',
        store: taskStore,
        sm: selections,
        clicksToEdit: 'auto',
        enableColumnHide:false,
        enableColumnMove:false,
		border:false,
		title:'All Tasks',
		iconCls:'icon-show-all',
		region:'center',
		
        plugins: completeColumn,

        columns: [
            completeColumn,
            {
                header: "Task",
                width:400,
                sortable: true,
                dataIndex: 'title',
                id:'task-title',
                editor: new Ext.form.TextField({
                    allowBlank: false
                })
            },
            {
                header: "Category",
                width:150,
                sortable: true,
                dataIndex: 'category',
                editor: new Ext.form.ComboBox({
                    displayField: 'text',
                    triggerAction: 'all',
                    mode:'local',
                    selectOnFocus:true,
                    listClass:'x-combo-list-small',
                    listeners: comboEvents
                })
            },
            {
                header: "Due Date",
                width: 150,
                sortable: true,
                renderer: Ext.util.Format.dateRenderer('D m/d/Y'),
                dataIndex: 'dueDate',
                groupRenderer: textDate(),
                groupName: 'Due',
                editor: new Ext.form.DateField({
                    format : "m/d/Y"
                })
            }
        ],

        view: new Ext.grid.GroupingView({
            forceFit:true,
            ignoreAdd: true,
            emptyText: 'No Tasks to display',

            templates: {
                header: headerTpl
            },

            getRowClass : function(r){
                var d = r.data;
                if(d.completed){
                    return 'task-completed';
                }
                if(d.dueDate && d.dueDate.getTime() < new Date().clearTime().getTime()){
                    return 'task-overdue';
                }
                return '';
            }
        })
    });

    var viewPanel = new Ext.Panel({
    	frame:true,
    	title: 'Views',
    	collapsible:true,
    	contentEl:'task-views',
    	titleCollapse: true
    });
    
    var taskActions = new Ext.Panel({
    	frame:true,
    	title: 'Task Actions',
    	collapsible:true,
    	contentEl:'task-actions',
    	titleCollapse: true
    });
    
    var groupActions = new Ext.Panel({
    	frame:true,
    	title: 'Task Grouping',
    	collapsible:true,
    	contentEl:'task-grouping',
    	titleCollapse: true
    });
    
    var actionPanel = new Ext.Panel({
    	id:'action-panel',
    	region:'west',
    	split:true,
    	collapsible: true,
    	collapseMode: 'mini',
        header: false,
    	width:200,
    	minWidth: 150,
    	border: false,
    	baseCls:'x-plain',
    	items: [taskActions, viewPanel, groupActions]
    });

    if(Ext.isAir){ // create AIR window
        var win = new Ext.air.MainWindow({
            layout:'border',
            items: [actionPanel, grid],
            title: 'Simple Tasks',
            iconCls: 'icon-show-all'
        }).render();
	}else{
        var viewport = new Ext.Viewport({
            layout:'border',
            items: [actionPanel, grid]
        });
    }

    var ab = actionPanel.body;
    ab.on('mousedown', doAction, null, {delegate:'a'});
	ab.on('click', Ext.emptyFn, null, {delegate:'a', preventDefault:true});

    grid.on('resize', syncFields);
	grid.on('columnresize', syncFields);

    grid.on('afteredit', function(e){
        if(e.field == 'category'){
            catStore.addCategory(e.value);
        }
        if(e.field == taskStore.getGroupState()){
            taskStore.applyGrouping();
        }

    });

    grid.on('keydown', function(e){
         if(e.getKey() == e.DELETE && !grid.editing){
             actions['action-delete']();
         }
    });

    selections.on('selectionchange', function(sm){
    	var bd = taskActions.body, c = sm.getCount();
    	bd.select('li:not(#new-task)').setDisplayed(c > 0);
    	bd.select('span.s').setDisplayed(c > 1);
    });

    // The fields in the grid's header
    var ntTitle = new Ext.form.TextField({
        renderTo: 'new-task-title',
        emptyText: 'Add a task...'
    });

    var ntCat = new Ext.form.ComboBox({
        renderTo: 'new-task-cat',
        disabled:true,
        displayField: 'text',
        triggerAction: 'all',
        mode:'local',
        selectOnFocus:true,
        listClass:'x-combo-list-small',
        listeners: comboEvents
    });

    var ntDue = new Ext.form.DateField({
        renderTo: 'new-task-due',
        value: new Date(),
        disabled:true,
        format : "m/d/Y"
    });

    // syncs the header fields' widths with the grid column widths
    function syncFields(){
        var cm = grid.getColumnModel();
        ntTitle.setSize(cm.getColumnWidth(1)-2);
        ntCat.setSize(cm.getColumnWidth(2)-4);
        ntDue.setSize(cm.getColumnWidth(3)-4);
    }
    syncFields();

    var editing = false, focused = false, userTriggered = false;
    var handlers = {
        focus: function(){
            focused = true;
        },
        blur: function(){
            focused = false;
            doBlur.defer(250);
        },
        specialkey: function(f, e){
            if(e.getKey()==e.ENTER){
                userTriggered = true;
                e.stopEvent();
                f.el.blur();
                if(f.triggerBlur){
                    f.triggerBlur();
                }
            }
        }
    }
    ntTitle.on(handlers);
    ntCat.on(handlers);
    ntDue.on(handlers);

    ntTitle.on('focus', function(){
        focused = true;
        if(!editing){
            ntCat.enable();
            ntDue.enable();
            syncFields();
            editing = true;
        }
    });

    // when a field in the add bar is blurred, this determines
    // whether a new task should be created
    function doBlur(){
        if(editing && !focused){
            var title = ntTitle.getValue();
            if(!Ext.isEmpty(title)){
                taskStore.addTask({
                    taskId: Task.nextId(),
                    title: title,
                    dueDate: ntDue.getValue()||'',
                    description: '', // ???
                    category: ntCat.getValue(),
                    completed: false
                });
                ntTitle.setValue('');
                if(userTriggered){ // if the entered to add the task, then go to a new add automatically
                    userTriggered = false;
                    ntTitle.focus.defer(100, ntTitle);
                }
            }
            ntCat.disable();
            ntDue.disable();
            editing = false;
        }
    }
	
    var actions = {
    	'view-all' : function(){
    		taskStore.applyFilter('all');
    		grid.setTitle('All Tasks', 'icon-show-all');
    	},
    	
    	'view-active' : function(){
    		taskStore.applyFilter(false);
    		grid.setTitle('Active Tasks', 'icon-show-active');
    	},
    	
    	'view-complete' : function(){
    		taskStore.applyFilter(true);
    		grid.setTitle('Completed Tasks', 'icon-show-complete');
    	},
    	
    	'action-new' : function(){
    		ntTitle.focus();
    	},
    	
    	'action-complete' : function(){
    		selections.each(function(s){
    			s.set('completed', true);
    		});
            taskStore.applyFilter();
    	},
    	
    	'action-active' : function(){
    		selections.each(function(s){
    			s.set('completed', false);
    		});
            taskStore.applyFilter();
    	},
    	
    	'action-delete' : function(){
    		Ext.Msg.confirm('Confirm', 'Are you sure you want to delete the selected task(s)?', 
    		function(btn){
                if(btn == 'yes'){
                	selections.each(function(s){
		    			taskStore.remove(s);
		    		});
                }
            });
    	},
    	
    	'group-date' : function(){
    		taskStore.groupBy('dueDate');
    	},
    	
    	'group-cat' : function(){
    		taskStore.groupBy('category');
    	},
    	
    	'no-group' : function(){
    		taskStore.clearGrouping();
    	}
    };
    
    function doAction(e, t){
    	e.stopEvent();
    	actions[t.id]();
    }
    
    
    // generates a renderer function to be used for textual date groups
    function textDate(){
        // create the cache of ranges to be reused
        var today = new Date().clearTime(true);
        var year = today.getFullYear();
        var todayTime = today.getTime();
        var yesterday = today.add('d', -1).getTime();
        var tomorrow = today.add('d', 1).getTime();
        var weekDays = today.add('d', 6).getTime();
        var lastWeekDays = today.add('d', -6).getTime();

        return function(date){
            if(!date) {
                return '(No Date)';
            }
            var notime = date.clearTime(true).getTime();

            if (notime == todayTime) {
                return 'Today';
            }
            if(notime > todayTime){
                if (notime == tomorrow) {
                    return 'Tomorrow';
                }
                if (notime <= weekDays) {
                    return date.format('l');
                }
            }else {
            	if(notime == yesterday) {
                	return 'Yesterday';
	            }
	            if(notime >= lastWeekDays) {
	                return 'Last ' + date.format('l');
	            }
            }            
            return date.getFullYear() == year ? date.format('D m/d') : date.format('D m/d/Y');
       }
    }
});

/* This is used to laod some demo tasks if the task database is empty */
function loadDemoTasks(store){
	var s = new Date();
	// hardcoded demo tasks
	store.addTask({taskId: Task.nextId(), title:'Start documentation of Ext 2.0', category:'Ext', description:'', dueDate: s.add('d', 21), completed: false});
	store.addTask({taskId: Task.nextId(), title:'Release Ext 1.l Beta 2', category:'Ext', description:'', dueDate:s.add('d', 2), completed: false});
	store.addTask({taskId: Task.nextId(), title:'Take wife to see movie', category:'Family', description:'', dueDate:s.add('d', 2), completed: false});
	store.addTask({taskId: Task.nextId(), title:'Finish task list demo app', category:'Ext', description:'', dueDate:s.add('d', 2), completed: false});
	store.addTask({taskId: Task.nextId(), title:'Do something other than work', category:'Family', description:'', dueDate:s.add('d', -1), completed: false});
	store.addTask({taskId: Task.nextId(), title:'Go to the grocery store', category:'Family', description:'', dueDate:s.add('d', -1), completed: true});
	store.addTask({taskId: Task.nextId(), title:'Reboot my computer', category:'Misc', description:'', dueDate:s, completed: false});
	store.addTask({taskId: Task.nextId(), title:'Respond to emails', category:'Ext', description:'', dueDate:s, completed: true});
}

    

