var DT = {
    'Util': new Object(),
    'Cookie': new Object(),
    'General': new Object(),
    'User': new Object(),
    'Recipe': new Object(),
    'Plan': new Object(),
    'RecipeOverview': new Object(),
    'RecipeSearch': new Object(),
    'ShoppingList': new Object(),
    'MyStuff': new Object()
}
/* SESSION STATE */

DT.Cookie.__get = function() {
    var dt_cookie = jQuery.cookie('DT')
    return dt_cookie ? $H(dt_cookie.evalJSON()) : $H({})
}

DT.Cookie.__save = function(dt_cookie) {
    jQuery.cookie('DT', dt_cookie.toJSON())
}

DT.Cookie.get = function(key) {
    var dt_cookie = DT.Cookie.__get()
    return dt_cookie.get(key)
}

DT.Cookie.set = function(key, val) {
    var dt_cookie = DT.Cookie.__get()
    dt_cookie.set(key, val)
    DT.Cookie.__save(dt_cookie)
}

DT.Cookie.del = function() {
    jQuery.cookie('DT', null)
}

/*  UTILIITY FUNCTIONS */

DT.Util.alert = function(msg, ttl) {
    var dialog = new Element('div', {'id': 'modal_alert_dialog'}).update('\
			<h2 class="ttl"></h2>\
			<span class="msg"></span>\
			<button class="center image confirm"><span>Ok</span></button>\
        ');
		
	if (typeof(ttl) != "undefined") {
		dialog.down('.ttl').update(ttl);
	}
    dialog.down('.msg').update(msg)
    Event.observe(dialog.down('button'), 'click', function(e) { DT.Util.alert.close() })
    var old_dialog = $('modal_alert_dialog')
    if(old_dialog) old_dialog.remove()
    
    $(document.body).insert({'bottom': dialog})
    jQuery('#modal_alert_dialog').modal()
}

DT.Util.alert.close = function() {
    jQuery.modal.close()
    $('modal_alert_dialog').remove()
}

DT.Util.prompt = function(msg, submit_text, cancel_text, callback, default_val, use_textarea) {
    var dialog = new Element('div', {'id': 'modal_prompt_dialog'}).update('\
            <form method="post" action="/" onsubmit="event.returnValue = false; return false;">\
                <h2 class="msg"></h2>\
                '+ (use_textarea ? '<textarea cols="45" rows="5" class="response"></textarea>' : '<input class="response" type="text" size="45" />')+'\
                <div class="button-row">\
                    <button class="image save-lg" type="submit"><span>Save</span></button>\
                    <button class="image cancel-lg" type="button"><span>Cancel</span></button>\
                </div>\
            </form>\
        ');
		
    dialog.down('.msg').update(msg)
    if(default_val) dialog.down('.response').value = default_val.strip()
    
    var old_dialog = $('modal_prompt_dialog')
    if(old_dialog) old_dialog.remove()
    
    $(document.body).insert({'bottom': dialog})    
    
    var form = dialog.down('form')
    Event.observe(form, 'submit', function(e) {
        var response = $F(dialog.down('.response')).strip()
        
        if(!response) {
            dialog.down('.msg').select('.error_message').invoke('remove')
            dialog.down('.msg').insert({'bottom': new Element('div', {'class': 'error_message'}).update('A response is required')})
        }
        else {
            DT.Util.prompt.close()
            callback(response)
        }
    })
    
    var submit = dialog.down('.save-lg')
    //submit.value = submit_text
    
    var cancel = dialog.down('.cancel-lg')
    //cancel.value = cancel_text
	
    Event.observe(cancel, 'click', function(e) {
        DT.Util.prompt.close()
    })
    
    jQuery('#modal_prompt_dialog').modal()
}

DT.Util.prompt.close = function() {
    jQuery.modal.close()
    $('modal_prompt_dialog').remove()
}

DT.Util.confirm = function(msg, submit_cls, cancel_cls, callback) {
    var dialog = new Element('div', {'id': 'modal_prompt_dialog'}).update('\
            <form method="post" action="/" onsubmit="event.returnValue = false; return false;">\
                <h2 class="msg">'+ msg +'</h2>\
                <div class="button-row">\
                    <button class="image '+ submit_cls +'" type="submit"><span>Save</span></button>\
                    <button class="image '+ cancel_cls +'" type="button"><span>Cancel</span></button>\
                </div>\
            </form>\
        ');
		
	var old_dialog = $('modal_prompt_dialog');
	if (old_dialog) old_dialog.remove();
	
	$(document.body).insert({'bottom': dialog});
	
	var form = dialog.down('form');
	Event.observe(form, 'submit', function(e) {
	    DT.Util.prompt.close();
	    callback()
	});
	
	var cancel = dialog.down('.'+cancel_cls);
	Event.observe(cancel, "click", function(e){
		DT.Util.prompt.close()
	});
	
	jQuery("#modal_prompt_dialog").modal();
}


/* GENERAL */

DT.General.RecentViews = new Object()
DT.General.RecentViews.show = function() {
    $('recently_viewed_recipes').select('li').invoke('show')
    $('recently-viewed').down('.show-more').hide()
    $('recently-viewed').down('.show-less').show()
}
DT.General.RecentViews.hide = function() {
    $('recently_viewed_recipes').select('li').each(function(o, i) {
        if(i >= 3) o.hide()
    })
    $('recently-viewed').down('.show-more').show()
    $('recently-viewed').down('.show-less').hide()
}

DT.General.CookingTonight = new Object()
DT.General.CookingTonight.show = function() {
    $('whats_cooking_tonight').select('li').invoke('show')
    $('cooking-tonight').down('.show-more').hide()
    $('cooking-tonight').down('.show-less').show()
}
DT.General.CookingTonight.hide = function() {
    $('whats_cooking_tonight').select('li').each(function(o, i) {
        if(i >= 3) o.hide()
    })
    $('cooking-tonight').down('.show-more').show()
    $('cooking-tonight').down('.show-less').hide()
}

/* USER FUNCTIONS */
DT.User.login = function(form, no_reload) {
    if(typeof(no_reload) != 'undefined') DT.User.login.no_reload = no_reload
    
    var params = ''
    if(form) {
        params = Form.serialize(form)
    }
    
    new Ajax.Request('/user/login', {
        parameters: params,
        onSuccess: function(t) {
            if(form) {
                DT.User.login.success(t)
            }
            else {
                var dialog = new Element('div', {'id': 'modal_user_login'})
                dialog.update(t.responseText)
                dialog.down('input[id=UserRedirectUrl]').value = window.location.href
                $(document.body).insert({'bottom': dialog});
                jQuery('#modal_user_login')
					.modal({
						minHeight:250,
						persist: true
					});
            }
        },
        onFailure: function(t) {
            var dialog = $('modal_user_login')
            dialog.update(t.responseText)
        }
    })
}

DT.User.login.no_reload = false

DT.User.login.success = function(response) {
    DT.Cookie.set('logged_in', true)
    if(DT.User.login.no_reload) {
        $('hd-nav').replace(response.responseText)
        facebook_init()
    }
    else {
        window.location.reload()
    }
}


DT.User.login.close = function() {
    jQuery.modal.close()
    if($('modal_user_login')) $('modal_user_login').remove()
}


DT.User.fb_login = function() {
    DT.User.login.close()
    FB.Connect.requireSession(function() {
        new Ajax.Request('/user/fb_login', {
            onSuccess: function(t) {
                jQuery.cookie('fb_connect', 'true')
                DT.User.login.success(t)
            },
            onFailure: function() {
                alert('Unable to connect to Facebook')
            }
        })
    })
}

DT.User.logout = function() {
    if(jQuery.cookie('fb_connect')) {
        jQuery.cookie('fb_connect', null)
        FB.Connect.logout(DT.User.logout)
    }
    
    DT.Cookie.del()
    window.location = '/user/logout'
}

DT.User.select_recipe_tab = function(link) {
    var li = $(link).up('li')
    
    $$('.tab').each(function(o) {
        o.removeClassName('on')
    })
    li.addClassName('on')
}


/* MAIN RECIPE PAGE */

DT.RecipeOverview.scrollTo = function() {
    $('search_recipe_tab').scrollTo();
}

DT.RecipeOverview.select_tab = function(link) {
    var li = $(link).up('li')
    
    $$('.overview-tab').each(function(o) {
        o.removeClassName('selected')
    })
    li.addClassName('selected')
    
    if (li.hasClassName('search-tab')) {
		if (jQuery.cookie('DT_last_search') !== null) {
			window.location = '/recipe/search'+ jQuery.cookie('DT_last_search') +"#search"+Math.floor(Math.random()*1001);
		} else {
			$('recipe_view_container').hide();
			$('search_results_container').show()
		}
		
	} else if (li.hasClassName('recipe-tab')) {
		if (jQuery.cookie('DT_last_recipe') !== null) {
			window.location = jQuery.cookie('DT_last_recipe')+Math.floor(Math.random()*1001);	
		} else {
			$('search_results_container').hide();
			$('recipe_view_container').show()
		}
	}
}

DT.RecipeOverview.load_recipe = function(url, keep_hidden) {
    new Ajax.Request(url, {
        parameters: {
            'data[Recipe][no_save_view]': keep_hidden ? 1 : 0
        },
        onSuccess: function(t) {
            DT.RecipeOverview.update_recipe_view(t.responseText, keep_hidden)
        }
    })
}

DT.RecipeOverview.update_recipe_view = function(content, keep_hidden) {
    $('recipe_view_container').update(content)
    if(!keep_hidden) {
        DT.RecipeOverview.select_tab('view_recipe_tab_link')
        DT.RecipeOverview.scrollTo()
        new Draggable('draggable_recipe', {
            ghosting: true,
            scroll: window,
            revert: true
        })
    }
}

DT.RecipeOverview.search_clear = function(){
	//jQuery.cookie('DT_last_search', null, {expires:0});
}

DT.RecipeOverview.search_store = function() {
	jQuery.cookie('DT_last_search', window.location.search, {expires: 1});
	jQuery.cookie('DT_last_recipe', arguments[0], {expires: 1});
	window.location = arguments[0];
}

/* RECIPE SEARCH */

DT.RecipeSearch.select_tab = function(li) {
    li = $(li)
    $$('#search_results_container .course-tab').each(function(o) {
        o.removeClassName('selected')
    })
    li.addClassName('selected')
}

DT.RecipeSearch.save = function(link) {
    link = $(link)
    var search_term = window.location.search
    DT.Util.prompt('Enter a name for this search:', 'Save', 'Cancel', function(name) {
        new Ajax.Request('/recipe/save_search', {
            parameters: {
                'data[SavedUserSearch][name]': name,
                'data[SavedUserSearch][search_term]': search_term
            },
            onSuccess: function(t) {
                link.replace('Search saved')
            }
        })
    })
}


/* RECIPE VIEW */

DT.Recipe.favorite = function(link, id) {
    link = $(link)
    new Ajax.Request('/recipe/save_favorite/'+id, {
        onSuccess: function(t) {
            link.replace('Recipe saved')
        }
    })
}

DT.Recipe.unfavorite = function(link, id, course_id) {
    link = $(link)
    link.up('li').remove()
    new Ajax.Request('/recipe/remove_favorite/'+id+'/'+course_id, {
        onSuccess: function(t) {
            $('my-recipe-container').update(t.responseText)
        }
    })
}


DT.Recipe.add_ingredient = function() {
    var form = $('recipe_edit_form')
    var row = $('ingredient_edit_clone_container').firstDescendant().cloneNode(true)
	var c = jQuery("li.ingredient-row").length;
	
    row.select('input').each(function(o) {
        var name = o.readAttribute('name')
        o.writeAttribute('name', name.replace(/000/, c))
    })
    row.select('select').each(function(o) {
        var name = o.readAttribute('name')
        o.writeAttribute('name', name.replace(/000/, c))
    })
    
    form.down('.add-ingredient-row').insert({'before': row})
}

DT.Recipe.remove_ingredient = function(link) {
    $(link).up('.ingredient-row').remove()
}


DT.Recipe.add_note = function(id, val) {
    if(!val) val = ''
    
    var container = $('recipe_user_note_container')
    if(container) {
        val = container.innerHTML.strip()
        val = val.replace(/<br\s*\/?>/g, "\r\n")
    }
    
    callback = function(response) {
        DT.Recipe.add_note_callback(id, response);
    }
    
    DT.Util.prompt('Enter Your Note:', 'Save', 'Cancel', callback, val, true)
}

DT.Recipe.add_note_callback = function(id, val) {
    new Ajax.Request('/recipe/add_note/'+id, {
        parameters: {
            'data[RecipeNote][content]': val
        },
        onSuccess: function(response) {
            DT.RecipeOverview.update_recipe_view(response.responseText)
        }
    })
}

DT.Recipe.del = function(link, id) {
	var li = $(link).up('li');	
	
	DT.Util.confirm('Delete Your Recipe:', 'confirm', 'cancel', function(name) {
		new Ajax.Request('/recipe/delete/'+id, {
		    onSuccess: function(t) {
		        li.remove()
		    }
		})
	});
}

DT.Recipe.review_flag = function(link, id, recipe_id) {
	new Ajax.Request('/recipe/review_flag/'+ id +'/'+ recipe_id, {
		onSuccess: function() {
			$(link).update('Review flagged as inappropriate');
		}
	})
}

DT.Recipe.recipe_flag = function(link, id) {
	new Ajax.Request('/recipe/recipe_flag/'+ id, {
		onSuccess: function() {
			$(link).update('Recipe flagged as inappropriate');
		}
	})
}

DT.Recipe.cancel_submit = function() {
	if (jQuery("fieldset#confirm-submit:visible").length) {
		jQuery("form#recipe_edit_form").children("fieldset").toggle();
		jQuery("#UserAcceptGuidelines").removeAttr("checked");
	} else {
		window.location='/user/my_stuff';
	}
}

DT.Recipe.confirm_submit = function(frm) {
	try {		
		var f = jQuery(frm);
		var e = 0;
		
		// rehide error messages
		f.find("li.error_message").hide();
		
		// validate title, description, ingredients, directions
		jQuery.each(frm.elements, function(){
			if (typeof(this) == "object" && typeof(this.name) != "undefined") {
				switch (this.name)
				{
					case "data[Recipe][name]":
					case "data[Recipe][description]":
					case "data[RecipeInstruction][instruction]":
						if (!this.value.strim().length) {
							jQuery("li#error-"+ /\]\[(.+)\]$/.exec(this.name)[1] ).show();
							e++;
						}
						break;
				}
			}
		});
		
		f.find("[name$='[quantity]']").each(function(){
			var i = /\]\[([0-9]+)\]\[/.exec(this.name)[1];
			var iq = this.value.strim().length
			var ig = f.find("[name$='["+ i +"][Ingredient][name]']").get(0).value.strim().length;
						
			if ((i == 0 && (!iq || !ig)) || (i > 0 && ((iq && !ig) || (!iq && ig)))) {
				jQuery("li#error-ingredient").show();
				e++;
			}
		});
		
		if (e == 0) {
			// valid, error-free recipe submission
			if (f.children("fieldset#confirm-submit:visible").length && f.find("#UserAcceptGuidelines").get(0).checked) {
				// submit
				return true;
				
			} else if (f.children("fieldset#form-body:visible").length) {
				// display guidelines and release
				f.children("fieldset").toggle();
				f.find("#UserAcceptGuidelines").removeAttr("checked");
			}
		};
	} catch (e) {
		//console.log( e );
		//alert(e);
	}
	
	return false;
}

String.prototype.strim = function(){
	return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}


/* MEAL PLANNER */

DT.Plan.open = function() {
    new Ajax.Request('/plan/hide_planner/0', {
		onSuccess: function() {
			$('mealplan_container').show()
            $('mealplan_container_closed').hide()
		}
	})
}

DT.Plan.close = function() {
    new Ajax.Request('/plan/hide_planner/1', {
		onSuccess: function() {
			$('mealplan_container').hide()
            $('mealplan_container_closed').show()
		}
	})
}

DT.Plan.on_drop = function(dropped, container, event) {
    var content = dropped.down('input[name=name]').value
    var recipe_id = dropped.down('input[name=id]').value
    var url = dropped.down('input[name=url]').value
    DT.Plan.add_item(content, recipe_id, url, container)
    
    DT.Plan.update()
}

DT.Plan.update = function() {
    var params = Form.serialize('mealplan_container')
    new Ajax.Request('/plan/save', {
        parameters: params,
        onSuccess: function(t) {
            var plan = t.responseJSON
            $('mealplan_id_input').value = plan.id
            $('mealplan_name_input').value = plan.name
            DT.Plan.resize_view()
            
            // user id is set on save, otherwise, it's not shareable...
            if(plan.user_id) {
                $('plan_share_link').show()
                $('plan_share_link').down('.addthis_button').writeAttribute('addthis:url', 'http://www.dinnertool.com/plan/view/' + plan.id)
                $('plan_share_link').down('.addthis_button').share.url = 'http://www.dinnertool.com/plan/view/' + plan.id
            }
            else {
                $('plan_share_link').hide()
            }
        }
    })
}


DT.Plan.add_item = function(content, recipe_id, url, list) {
    list = $(list)
    var day = list.down('input[name=day_of_week]').value
    
    var recipe_link = new Element('a', {'class': 'recipe', 'href': 'javascript: void(0);'}).update(content)
    Event.observe(recipe_link, 'click', function(e) {
        DT.RecipeOverview.load_recipe(url)
    })

    var li = new Element('li', {'class': 'recipe-item item'}).update(recipe_link)
    var input = new Element('input', {'type': 'hidden','name':'data[PlanRecipe]['+day+'][]','value':recipe_id})
    
    var link = new Element('a', {'href': 'javascript: void(0);', 'class': 'remove'}).update('[x]')
    Element.observe(link, 'click', function(e) {
        DT.Plan.remove_item(Event.element(e))
    })
    
    li.insert({'bottom': input})
    li.insert({'bottom': '&nbsp;&nbsp;'})
    li.insert({'bottom': link})
    
    var recipe_items = list.select('.recipe-item')
    var first_note = list.down('.note-item')
    
    // insert at bottom of recipes
    if(recipe_items.size()) {
        recipe_items.pop().insert({'after': li})
    }
    else if(first_note) {
        first_note.insert({'before': li})
    }
    else {    
        list.insert({'bottom': li})
    }
    
    list.removeClassName('empty-list')
    list.up('.mealplan-day').removeClassName('empty-list')
}

DT.Plan.remove_item = function(link) {
    var li = $(link).up('li')
    var list = li.up('.mealplan-day-list')
    li.remove()
    
    if(0 == list.select('.item').size()) {
        list.addClassName('empty-list')
        list.up('.mealplan-day').addClassName('empty-list')
    }
    DT.Plan.update()
}


DT.Plan.add_note_callback = function(list) {
    return function(note) {
        DT.Plan.add_note(list, note)
    }
}

DT.Plan.add_note = function(list, note, skip_save) {
    list = $(list)
    note = note.strip()
    if(!note) return // skip empty submissions
    
    var day = list.down('input[name=day_of_week]').value
    var li = new Element('li', {'class': 'note-item item'}).update(note)
    var input = new Element('input', {'type':'hidden','name':'data[PlanNote]['+day+'][]','value':note})
    var link = new Element('a', {'href': 'javascript: void(0);', 'class': 'remove'}).update('[x]')
    Event.observe(link, 'click', function(e) {
        DT.Plan.remove_item(Event.element(e))
    })
    
    li.insert({'bottom': input})
    li.insert({'bottom': '&nbsp;&nbsp;'})
    li.insert({'bottom': link})
    list.insert({'bottom': li})
    
    list.removeClassName('empty-list')
    list.up('.mealplan-day').removeClassName('empty-list')
    if(!skip_save) DT.Plan.update()
}


DT.Plan.new_plan = function(redirect_url) {
    if(!redirect_url) redirect_url = window.location.href
    window.location = '/plan/clear_current?redirect_url='+escape(redirect_url)
}

DT.Plan.create_random = function(redirect_url) {
    if(!redirect_url) redirect_url = window.location.href
    window.location = '/plan/create_random?redirect_url='+escape(redirect_url)
}

DT.Plan.save = function() {
    var old_name = $('mealplan_name_input').value
    var callback = function(name) {
        var input = $('mealplan_name_input')
        input.value = name.strip()
        DT.Plan.update();
		
		DT.Util.alert(
			'Your Meal Plan has been saved.  Click the My Stuff section to retrieve all saved Meal Plans.',
			'Enter a name for this Meal Plan:'
		);
    };
	
	if (!jQuery(":input[name^='data[PlanRecipe]']").length) {
		DT.Util.alert(
			'Please add recipes to your Meal Plan before saving.',
			'Enter a name for this Meal Plan:'
		);	
	} else {
    	DT.Util.prompt('Enter a name for this Meal Plan:', 'Save', 'Cancel', callback, old_name)
	}
}

DT.Plan.export_to_shopping_list = function() {
    var id = $('mealplan_id_input').value.strip()
    if(!id) return DT.Util.alert('You must create a meal plan before you can export it')
    
    window.location = '/shopping_list/view/plan:' + id
}

DT.Plan.resize_view = function() {
    var min_height = 140;
    lists = $('mealplan_container').select('.mealplan-day-list')
    var max_height = lists.max(function(list) { 
            var children = list.descendants()
            var first = children.shift()
            var last = children.pop()
            return last.cumulativeOffset().top + last.getHeight() - first.cumulativeOffset().top
        })

    lists.each(function(o) {
        o.setStyle({
            'height': Math.max(min_height, max_height) + 'px'
        })
    })
}

DT.Plan.del = function(link, id) {
    var li = $(link).up('li')
    new Ajax.Request('/plan/delete/'+id, {
        onSuccess: function(t) {
            li.remove()
        }
    })
}


/* SHOPPING LISTS */

DT.ShoppingList.max_item_id = null
DT.ShoppingList.prior_state = null
DT.ShoppingList.sponsor_deleted = false

DT.ShoppingList.__aisles = function() {
    return $('shopping_list_container').select('.shopping-list-aisle')
}

// turn off editing
DT.ShoppingList.view = function() {
    var aisles = DT.ShoppingList.__aisles()
    aisles.each(function(aisle) {
        Sortable.destroy(aisle)
        aisle.select('.shopping-list-item').each(function(li) {
            DT.ShoppingList.__unmake_editable_item(li)
        })
    })
    
    $('edit_shopping_list_btn').show()
    $('save_shopping_list_btn').hide()
    $('cancel_edit_shopping_list_btn').hide()
    $('shopping_list_container').select('.add-item').invoke('hide')
}

// turn on editing
DT.ShoppingList.edit = function() {
    DT.ShoppingList.prior_state = $('shopping_list_container').cloneNode(true)
    
    var aisles = DT.ShoppingList.__aisles()
    aisles.each(function(aisle) {
        var items = aisle.select('.shopping-list-item')
        items.each(function(item) {
            DT.ShoppingList.__make_editable_item(item)
        })
        if(0 == items.size()) {
         DT.ShoppingList.add_item(aisle)
         DT.ShoppingList.add_item(aisle)
        }
    })
    
    DT.ShoppingList.make_sortable()
    $('edit_shopping_list_btn').hide()
    $('save_shopping_list_btn').show()
    $('cancel_edit_shopping_list_btn').show()
    $('shopping_list_container').select('.add-item').invoke('show')
}

DT.ShoppingList.revert = function() {
    DT.ShoppingList.view() // cheap way to remove the sortables
    $('shopping_list_container').replace(DT.ShoppingList.prior_state)
}

DT.ShoppingList.save = function(add_sponsor, sponsor_name) {
    if(DT.Cookie.get('logged_in')) {
        var name = $('shopping_list_name_input').value.strip()
        if(name) {
            DT.ShoppingList.save_callback(name, add_sponsor, sponsor_name)
        }        
        else {      
            callback = function(response) {
                DT.ShoppingList.save_callback(response, add_sponsor, sponsor_name)
            }
            DT.Util.prompt('Name your shopping list:', 'Save', 'Cancel', callback, $('shopping_list_name_input').value.strip())
        }
    }
    else {
        DT.User.login(null, true)
    }
}

DT.ShoppingList.save_callback = function(name, add_sponsor, sponsor_name) {
    // do saving
    // must serialize manually
    
    var params = new Hash()
    params.set('data[ShoppingList][id]', $('shopping_list_id_input').value)
    params.set('data[ShoppingList][plan_id]', $('shopping_list_plan_id_input').value)
    params.set('data[ShoppingList][name]', name.strip())
    
    $('shopping_list_container').select('.shopping-list-aisle').each(function(aisle) {
        var aisle_id = aisle.id.match(/\d+$/)
        var vals = []
        var sponsor_added = false

        aisle.select('.shopping-list-item').each(function(item) {
            var val = item.down('.content') ? item.down('.content').value.strip() : item.innerHTML.replace(/\s+/g, ' ')
            if(!val)
                item.remove()
            else
                vals.push(val)
            
            if (val == sponsor_name) sponsor_added = true
        })
        
        //add sponsor to 'Other' aisle (aisle_id == null)
        if (add_sponsor && !sponsor_added && !DT.ShoppingList.sponsor_deleted && aisle_id == null) {
            vals.push(sponsor_name)
            DT.ShoppingList.add_item(aisle, sponsor_name)
        }
        
        var key = 'data[Aisle][id]['+aisle_id+'][]';
        params.set(key, vals)
    })
    
    new Ajax.Request('/shopping_list/save/', {
        parameters: params,
        onSuccess: function(t) {
            var shopping_list = t.responseJSON
            
            // when the shopping list is initially created,
            // reload the page so that the url is now correct
            if(!$('shopping_list_id_input').value) {
                window.location = '/shopping_list/view/'+shopping_list.id
            }
            else {
                $('shopping_list_id_input').value = shopping_list.id
                $('shopping_list_name_input').value = shopping_list.name
                $('shopping_list_plan_id_input').value = shopping_list.plan_id
                $('shopping_list_rename_link').show()
                $('shopping_list_name_display').update(shopping_list.name)
                DT.ShoppingList.view()
            }
        }
    })
}

DT.ShoppingList.rename = function() {
    DT.Util.prompt('Name your shopping list:', 'Save', 'Cancel', DT.ShoppingList.rename_callback, $('shopping_list_name_input').value.strip())
}

DT.ShoppingList.rename_callback = function(name) {
    var params = new Hash()
    params.set('data[ShoppingList][id]', $('shopping_list_id_input').value)
    params.set('data[ShoppingList][name]', name.strip())
    
    new Ajax.Request('/shopping_list/rename/', {
        parameters: params,
        onSuccess: function(t) {
            var shopping_list = t.responseJSON
            
            // when the shopping list is initially created,
            // reload the page so that the url is now correct
            $('shopping_list_name_input').value = shopping_list.name
            $('shopping_list_name_display').update(shopping_list.name)
        }
    })
}


DT.ShoppingList.make_sortable = function() {
    var aisles = DT.ShoppingList.__aisles()
    aisles.each(function(aisle) {
        Sortable.create(aisle, {
            only: 'shopping-list-item',
            containment: aisles,
            scroll: window,
            dropOnEmpty: true,
            handles: aisle.select('.shopping-list-item .handle')
        })
    })
}

DT.ShoppingList.add_item = function(list, text) {
    if(!text) text = ''
    var id = 'shopping_list_item_' + (++DT.ShoppingList.max_item_id)
    var li = new Element('li', {'class': 'shopping-list-item', 'id': id}).update(text)
    $(list).insert({'bottom': li})
    DT.ShoppingList.__make_editable_item(li)
}

DT.ShoppingList.add_item_callback = function(list) {
    return function(text) {
        DT.ShoppingList.add_item(list, text)
        DT.ShoppingList.make_sortable()
    }
}

DT.ShoppingList.__make_editable_item = function(li, text) {
    li = $(li)
    li.cleanWhitespace()
    if(typeof(text) == 'undefined') text = li.innerHTML.strip()
    
    text = text.unescapeHTML()
    
    var input = new Element('input', {'class': 'content', 'type': 'text', 'value': text})
    var handle = new Element('a', {'class': 'handle', 'href': 'javascript: void(0);'}).update('...')
    var close = new Element('a', {'class': 'close', 'href': 'javascript: void(0);'}).update('[x]')
    Event.observe(close, 'click', function(e) {
        if (Event.element(e).up('li').down('input').value == DT.ShoppingList.sponsor_name) {
            DT.ShoppingList.sponsor_deleted = true
        }
        Event.element(e).up('li').remove()
    })
    
    li.update('')
    li.insert({'bottom': handle})
    li.insert({'bottom': input})
    li.insert({'bottom': close})
    li.addClassName('edit')
}

DT.ShoppingList.__unmake_editable_item = function(li) {
    li = $(li)
    li.update($F(li.down('.content')).strip())
    li.removeClassName('edit')
}


DT.ShoppingList.del = function(link, id) {
    var li = $(link).up('li')
    new Ajax.Request('/shopping_list/delete/'+id, {
        onSuccess: function(t) {
            li.remove()
        }
    })
}


/*  MY STUFF */

DT.MyStuff.resize_view = function(container, expand) {
    container = $(container)
    
    var min_height = 246;
    list = container.down('ol')
    
    if(expand) {
        list.select('li').each(function(li) {
            li.show()
        })
        
        container.down('.show-more').hide()
        container.down('.show-less').show()
    }
    else {
        var items = list.select('li')
        var current_index = items.size() - 1
        while(current_index > 1) {
            if(container.getHeight() > min_height) {
                items[current_index--].hide()
            }
            else {
                break
            }
        }
        container.down('.show-more').show()
        container.down('.show-less').hide()
    }
    
    var i = 0;
    if(container.getHeight() < min_height) {
        var li = new Element('li', {'class': 'filler'}).update('&nbsp;')
        li.setStyle({
            'height': (min_height - container.getHeight()) + 'px'
        })
        list.insert({'bottom': li})
    }
}

