$(document).ready(function(){

//// Site Variables \\\\

//// Site Functions \\\\

function getKey(e) {
	var code;
	if (!e) var e = window.event;
	if (e.keyCode) code = e.keyCode;
	else if (e.which) code = e.which;
	var character = String.fromCharCode(code);
	return character;
}

//// User Module \\\\

var user = new (function User() {
    
    var password = $.cookie('password') || '';
    
    function loginUser(password){
        $.cookie('password', password);
        $('#adminPanel').show();
    }
    
    function logoutUser(){
        $.cookie.remove('password');
        password = '';
        $('#adminPanel').hide();
    }
    
    //start user off logged in.
    if (password) {
        loginUser(password);
    }
    
    this.login = function(callback, scope){
        if (!password) {
            password = prompt('Please enter your possword.');
            $.post('/', { validate: true, password: password }, function(responce){
                if (password == responce) {
                    loginUser(password);
                    alert('You are now logged in. :D');
                }
                else {
                    alert('Incorrect password, try again.');
                }
            });
        }
        else {
            var yes = confirm('You are already logged in on this machine, would you like to log out?');
            if (yes) {
                this.logout();
            }
        }
    };
    
    this.logout = function(){
        logoutUser();
    };
        
    this.validate = function(){
        return $.cookie('password');
    };
    
})();


//// Menu Module \\\\

var menu = new (function Menu() {
    
    var data = {};
    
    var datatypes = {
        'undefined' : 'text',
        'boolean'   : 'checkbox',
        'string'    : 'text',
        'number'    : 'text'
    };
    
    var Updater = new (function UpdateMangager(){
        
        var updates = [];
        
        var delay = 250;
        function run(){
            if (location.hash === '#editmenu')
            for (var i = 0, n = updates.length; i < n; i++) {
                updates[i]();
            }
        }
        
        var id = setInterval(run, delay);
        
        this.add = function(fn) {
            updates.push(fn);
        };
        
        this.clear = function(){
            updates = [];
        };
        
    })();
        
    this.edit = function(){
        
        Updater.clear();
        
        var el = $('<div></div>');

        var save = $('<input class="saverevert" type="button" value="Save Changes" />').attr('disabled', true).click(function(){
            if (!$(this).attr('disabled')) {
                menu.save();
            }
        });
        var revert = $('<input class="saverevert" type="button" value="Revert Changes" />').attr('disabled', true).click(function(){
            if (!$(this).attr('disabled')) {
                menu.load();
            }
        });
        
        
        var DataInput = function(data, name, datatype){
            
            var value = data[name];
            datatype = datatype || typeof value;
            var html = '<input class="CLASS" type="TYPE" name="NAME" value="VALUE" />';
            
            type = datatypes[datatype];
            
            html = html.replace('TYPE', type || 'text');
            html = html.replace('NAME', name);
            html = html.replace('VALUE', value);
            html = html.replace('CLASS', datatype + 'field');
            
            var el = $(html);
            var val = undefined;
            
            if (datatype === 'boolean') el.attr('checked', data[name]);
            
            function update(){
                var newval = datatype === 'boolean' ? el.attr('checked') :
                             datatype === 'number' ? parseFloat(el.attr('value')) :
                             el.attr('value');
                             
               if (datatype === 'number' && isNaN(newval) ) newval = 0;
                             
                //init
                if (val === undefined) {
                    val = newval;
                    //window.console.log('init!')
                }
                
                //update
                if (newval !== val){
                    val = newval;
                    data[name] = newval;
                    save.attr('disabled', false);
                    revert.attr('disabled', false);
                    //window.console.log('update!')
                }
                
            }
            
            Updater.add(update);
            
            return el;
        };
        
        
        var p = 0;
        function piano(){
            p++;
            return p % 2 ? 'odd' : 'even';
        }
        
        for (var area in data) {
        (function(area){
            var ele = $('<div class="sectionwrapper"></div').addClass( piano() ).appendTo(el);
            var n = area;
            $('<input class="removeclassbutton" type="button" value="Remove This Section" />').appendTo(ele).click(function(){
                var yeah = confirm('Would you like to remove section: ' + n);
                if (yeah) {
                    delete data[n];
                    menu.edit();
                    $('.saverevert').attr('disabled', false);
                }
            });
            
            $('<h3>' + area + '</h3>').appendTo(ele).click(function(){
                var name = area;
                var newname = prompt('Enter a new name for this area.', name);
                if (newname !== name) {
                    var olddata = data[name];
                    delete data[name];
                    data[newname] = olddata;
                    menu.edit();
                    $('.saverevert').attr('disabled', false);
                }
            });
            
            $('<div class="whatswhat"><label class="stringfield">name</label><label class="numberfield">price</label><label class="booleanfield">vegitarian</label><label class="booleanfield">vegan</label></div>').appendTo(ele);
            
            $.each(data[area], function(i) {
                
                var wrap = $('<div class="item"></div>').appendTo(ele);
                
                var name = new DataInput(this, 'name', 'string').appendTo(wrap);
                var price = new DataInput(this, 'price', 'string').removeClass('stringfield').addClass('numberfield').appendTo(wrap);
                var vegitarian = new DataInput(this, 'veggie', 'boolean').appendTo(wrap);
                var vegan = new DataInput(this, 'vegan', 'boolean').appendTo(wrap);
                
                vegan.change(function(){
                    if ($(this).attr('checked')) vegitarian.attr('checked', true).change();
                });
                vegitarian.change(function(){
                    if (!$(this).attr('checked')) vegan.attr('checked', false).change();
                });
                
                var del = $('<input type="button" value="remove" />').appendTo(wrap).click(function(){
                    data[area].splice(i, 1);
                    menu.edit();
                    $('.saverevert').attr('disabled', false);
                });
            });
            
            $('<input type="button" value="Add New Item" />').appendTo(ele).click(function(){
                data[n].push({
                    name  : 'New Item',
                    price : '',
                    vegan : false,
                    veggy : false
                });
                menu.edit();
                $('.saverevert').attr('disabled', false);
            }).wrap('<div class="addbuttonwrapper"></div>');
            
        })(area);
        }
            $('<input type="button" value="Add New Section" />').appendTo(el).click(function(){
                var title = prompt('Please enter a name for the new section');
                if (title === null) return false;
                data[title] = [];
                data[title].push({
                    name  : 'New Item',
                    price : 0.00,
                    vegan : false,
                    veggy : false
                });
                menu.edit();
                $('.saverevert').attr('disabled', false);
            }).wrap('<div class="adsectionwrapper"></div>');
        
        save.appendTo(el);
        revert.appendTo(el);
        $('#menuDisplay').html('').append(el);
        
    };
    
    this.load = function(){
        $.post('/', { area:'menudata' }, function(responce){
            data = $.json(responce);
            admin.message('Menu Loaded');
            menu.edit();
            menu.create();
        });
    };
    
    this.save = function(){
        var valid = user.validate();
        if (valid) {
            $.post('/', { password:$.cookie('password'), area:'menudata', content:$.json(data) }, function(responce){
                admin.message('Menu Saved');
                menu.edit();
                menu.create();
            });
        }
    };
    
    this.create = function() {
        
        var piano = 1;
        
        var menuarea = $('#menutime').html('');
        for (var section in data) {
            $('<h3>' + section + '</h3>').appendTo(menuarea);
            var dis = $('<div class="sectiondisplay"></div>').appendTo(menuarea);
            var items = data[section];       
            $.each(items, function(i, item){
               
               piano++;
               
               $('<div class="menuitem"><span class="itemname">' + this.name + '</span><span class="itemprice">' + this.price + '</span></div>')
                   .addClass( this.vegan ? 'vegan' : this.veggy ? 'veggy' : 'meaty')
                   .appendTo(dis)
                   .addClass( piano % 2 ? 'odditem' : 'evenitem' ).
                   css( i == items.length - 1 ? {} : {
                       borderBottom: '1px #CDCDCD dotted'
                   });
               
            });
        }
    };
    
    this.load();

})();

//// Keyboard Module \\\\

var keyboard = new (function Keyboard(){
    
    var map = {};
    var string = [];
    var phrases = {};

    $(document).keydown(function(e){
        var key = getKey(e).toLowerCase();
        map[key] = true;
        string.push(key);
        string = string.slice(Math.max(0, string.length - 25), string.length);
        
        var typed = string.join('');
        for (var phrase in phrases) {
            var index = typed.lastIndexOf(phrase);
            if (index >= 0 && index === typed.length - phrase.length) {
                phrases[phrase]();
            }
        }
        
    }).keyup(function(e){
        var key = getKey(e).toLowerCase();
        map[key] = false;
    });
    
    $(window).blur(function(){
        map = {};
    });
    
    this.setTrigger = function(name, action, scope){
        phrases[name] = function(){ action.apply(scope); };
    };
    
    this.removeTrigger = function(name){
        phrases[name] = false;
        delete phrases[name];
    };

    this.isDown = function(key){
        return map[key];
    };
    
    this.isUp = function(key){
        return !map[key];
    };
    
})();

//// Administration Module \\\\

var admin = new(function(){
    
    var textEditing = false;
    
    function message(txt){
        $('#adminPanel #message').css({opacity: 0}).text(txt).animate({opacity: 1}, 1000, function(){
            var self = this;
            setTimeout(function(){
                $(self).animate({opacity: 0}, 3000, function(){
                    $(self).text('');
                });
            }, 3000);
        });
    }
    
    function deactivateEditing(){
        if (!textEditing) return false;
        $('.editableToolbar').remove();
        $('.editableText').removeClass('editableText');
        textEditing = false;
    }
    
    function activateEditing(){
        if (textEditing) return false;
        $('.editable').each(function(){
            var area = $(this).attr('id'.replace('area_', ''));
            var config = {
                newlinesEnabled: area.indexOf('title') > 0 ? false : true,
            };
            $(this).editableText(config).change(function(){
				var content = $(this).html();
			    $.post('/', {
                    password: $.cookie('password'),
                    content: content,
                    area: area
                }, function(r){
                    if (r == content) {
                        message('Changes Saved!');
                    }
                    else {
                        message('Error encountered. Your changes were not saved.');
                    }
                });
            });
        });
        textEditing = true;
    }
    
    $('#adminPanel').css({opacity:0.8});
    
    var editbutton = $('#adminPanel .edit-text').click(function(){
       if (textEditing) {
           deactivateEditing();
           this.value = 'Start Editing Text';
       }
       else {
           activateEditing();
           this.value = 'Stop Editing Text';
       }
    });
    
    $('#adminPanel .edit-menu').click(function(){
        if (textEditing) {
            deactivateEditing();
            editbutton.value = 'Start Editing Text';
        }
        menu.load();
        navigation.go('#editmenu');
    });
    
    $('#adminPanel .logout').click(function(){
       user.logout();
       deactivateEditing();
    });
    
    this.startEditing = function(){
        activateEditing();
    };
    
    this.hidePanel = function(){
        $('#adminPanel').hide();
    };
    
    this.showPanel = function(){
        $('#adminPanel').show();
    };
    
    this.message = function(text){
        message(text);
    };
    
})();

//// Navigation Module \\\\
	
var navigation = new (function Navigation(){
    
    var homeHash = '#home';
    var startpage = location.hash || homeHash;
	var current = '';
	
    function goToPage(page) {
		if (page !== this.current) {
			var others = $('#swap div.swappable');
			var hash = (page == '#') ? homeHash : page;
			others.animate({opacity: 0}, 250, null, function(){
				$(this).appendTo('#stock');
			});
			var div = $('#area_' + hash.replace('#', ''));
            div.stop(true).css({opacity:0}).appendTo('#swap').animate({opacity:1}, 1000).css('min-height', '100%').css('height', 'auto');
            current = hash;
            location.hash = hash;
            
		    $('#navigation a[href!=LINK]'.replace('LINK', hash)).each(function(){
                $(this).data('on', false).trigger('mouseout');
            });
            $('#navigation a[href=LINK]'.replace('LINK', hash)).data('on', true).stop().animate({marginTop: 6}, 100);
		}
	};
    
	function update(){
        var hash = location.hash || homeHash;
        if (hash === '#login') {
            setTimeout(function(){
                user.login();
            }, 1000);
            hash = homeHash;
        }
		goToPage(hash);
	};
    
	$('#navigation a').each(function(){
		$(this).data('on', false);
        $(this).mouseover(function(){
            var on = $(this).data('on');
			if (!on) $(this).animate({marginTop: 3}, 300);
		})
		.mouseout(function(){
            var on = $(this).data('on');
			if (!on) $(this).animate({marginTop: 0}, 100);
		})
		.click(function(event){
			var href = $(this).attr('href');
			event.preventDefault();
			location.hash = href == location.hash ? '' : href;
			update();
			return false;
		});
	});
    
    this.go = goToPage;
    this.update = update;
    
    update();
})();

keyboard.setTrigger('login', user.login, user);

});
