

// Load the application once the DOM is ready, using `jQuery.ready`:
$(function(){

  // URL routing
  window.URLRouter = Backbone.Router.extend ({
	  
	 routes: {
		 "": 					"showRoot",
		 "cat:cat":				"showCategory",	// #catn
		 "project:project":		"showProject"	// #projectn
	 },
	 
	 showRoot: function() {
	   App.showCategory(Categories.categoryList.at(0));
	 },
	 
	 showCategory: function(categoryID) {
		 var c = Categories.categoryList.get("cat" + categoryID);
		  App.showCategory(c);
	 },
	 
	 showProject: function(projectID) {
		 var p = Projects.projectList.get("project" + projectID);
		 App.showProject(p);
	 }
  });
	
  window.Router = new URLRouter;
  
  // Category Model
  // ----------

  // Our basic **Category** model
  window.Category = Backbone.Model.extend({
	  
    // Default attributes for a category item.
    defaults: function() {
      return {
        current:  false
		};
    }
	
  });


  // Category Collection
  // ---------------

  // The collection of categories
  window.CategoryList = Backbone.Collection.extend({

    // Reference to this collection's model.
    model: Category,

    // 
    localStorage: new Store("categories", categories)
	
  });


  // Category navigator
  window.CategoryNavigator = Backbone.Model.extend({
    categoryList: new CategoryList,
	
	clearCurrent: function(i) {
		i.set({current: false});
	},
	
	setCurrent: function(c) {
		this.categoryList.each(this.clearCurrent);
		c.set({current: true});
		
		this.set({currentCategory: c});
	},
	
	setFirstCurrent: function() {
		this.setCurrent(this.categoryList.at(0));
	}
	
  });

  // Create our global category navigator
  window.Categories = new CategoryNavigator;


  // Category Item View
  // --------------

  // The DOM element for a category...
  window.CategoryView = Backbone.View.extend({

    //... is a div tag.
    tagName:  "span",

    // Cache the template function for a single category.
    template: _.template($('#category-template').html()),

    // The DOM events specific to an category.
    events: {
	  "mouseover"			: "over",
	  "mouseout"			: "out",
      "click"              	: "setCurrent"
    },

    // The CategoryView listens for changes to its model, re-rendering.
    initialize: function() {
		this.model.bind('change', this.render, this);
    },

    // Re-render the contents of the category.
    render: function() {
      $(this.el).html(this.template(this.model.toJSON()));

      return this;
    },
	
	over: function() {
		if (this.model.get("current")) return;
		this.$('.categoryNavItem').addClass("categoryNavItemOver");
	},
	
	out: function() {
		this.$(".categoryNavItem").removeClass("categoryNavItemOver");
		
	},
	
	setCurrent: function() {
		if (Projects.get("currentProject")) {
			Categories.setCurrent(this.model);
		}
		else {
			Router.navigate(this.model.id, true);
		}
	}
	
  });


  // Project Model
  // ----------
  window.Project = Backbone.Model.extend({
	 // Default attributes for a project item.
	defaults: function() {
	  return {
	    current:  false,
		exclude:  false,
		shrink: false
	  };
	},
	
    // The Project model listens for changes to the current category
    initialize: function() {
	  Categories.bind('change:currentCategory', this.categoryChange, this);
	  Projects.bind('change:currentProject', this.projectChange, this);
    },
	
	// determine if this project is a member of the current category
	// set "exclude" to true if not
	categoryChange: function() {
		var cc = Categories.get('currentCategory');
		var ccCats = cc.get('categories');		
		var pCats = this.get('categories');

		var ex = true;
		for (var ci = 0; ci < ccCats.length; ci++) {
			for (var pi = 0; pi < pCats.length; pi++) {
				if (ccCats[ci] == pCats[pi]) {
					ex = false;
					break;	
				}
			}
		}
		this.set({exclude: ex});
	},
	
	projectChange: function() {		
		var cp = Projects.get('currentProject');
		
		this.set({shrink: cp != null})
	}
	

  });

  // Project Collection
  // ---------------

  // The collection of Projects is backed by *localStorage* instead of a remote
  // server.
  window.ProjectList = Backbone.Collection.extend({

    // Reference to this collection's model.
    model: Project,

    // Save all of the projects under the `"Projects"` namespace.
    localStorage: new Store("projects", projects)

  });
  
  
  // Project navigator
  // --------------
  window.ProjectNavigator = Backbone.Model.extend({
   projectList: new ProjectList,
	
	clearCurrent: function(i) {
		i.set({current: false});
	},
	
	setCurrent: function(p) {
		this.projectList.each(this.clearCurrent);
		p.set({current: true});
		
		this.set({currentProject: p});
	
	  // and show the project
	  if (typeof ProjectViewer == "undefined") {
			window.ProjectViewer = new ProjectView({model: p}); 
			$("#currentProject").append(window.ProjectViewer.render().el);
	  }
	  else {
		ProjectViewer.model = p;
		ProjectViewer.render(p);
	  }	
	  
	},
	
	setNoCurrent: function() {
		this.projectList.each(this.clearCurrent);
		this.set({currentProject: null});
	}
	
  });

  // Create our global project navigator
  window.Projects = new ProjectNavigator;


  // Project Item View
  // --------------

  // The DOM element for a projectItem...
  window.ProjectItemView = Backbone.View.extend({

    //... is a div tag.
    tagName:  "div",

    // Cache the template function for a single projectItem.
    template: _.template($('#project-item-template').html()),

    // The DOM events specific to a project item.
    events: {
      "mouseover"      : "over",
      "mouseout"       : "out",
      "click"          : "showProject"
    },

    // The ProjectItemView listens for changes to its model, re-rendering.
    initialize: function() {
      this.model.bind('change:exclude', this.exclusionChange, this);
      this.model.bind('change:shrink', this.shrinkChange, this);
      this.model.bind('change:current', this.currentChange, this);
    },

    // Render the contents of the projectItem.
    render: function() {
      $(this.el).html(this.template(this.model.toJSON()));
      return this;
    },
	
	over: function() {
		if (this.model.get("exclude")) return;
		
		if (this.model.get("shrink") && !this.model.get("current")) {
			this.$('.projectItem').addClass("projectItemShrinkOver");
		}
		else {
			this.$('.projectItemDetails').addClass("pidOver");
		}
	},

	out: function() {
		if (this.model.get("exclude")) return;

		this.$('.projectItemDetails').removeClass("pidOver");
		this.$('.projectItem').removeClass("projectItemShrinkOver");
	},
	
	showProject: function() {
	  if (this.model.get("exclude")) return;

	  Router.navigate(this.model.id, true);
	},
	
	exclusionChange: function() {
		if (this.model.get("exclude")) {
			this.$('.projectItem').addClass("projectItemExclude");	
			this.$('.projectItemImage').addClass("projectItemImageExclude");	
			this.$('.projectItemDetails').addClass("projectItemDetailsExclude");	
		}
		else {
			this.$('.projectItem').removeClass("projectItemExclude");	
			this.$('.projectItemImage').removeClass("projectItemImageExclude");	
			this.$('.projectItemDetails').removeClass("projectItemDetailsExclude");	
		}
	},
	
	shrinkChange: function() {
		if (this.model.get("shrink")) {
			this.$('.projectItem').addClass("projectItemShrink");	
			this.$('.projectItemDetails').addClass("dontDisplay");	
		}
		else {
			this.$('.projectItem').removeClass("projectItemShrink");	
			this.$('.projectItemDetails').removeClass("dontDisplay");	
		}
	},
	
	currentChange: function() {
		if (this.model.get("current")) {
			this.$('.projectItem').addClass("projectItemCurrent");	
		}
		else {
			this.$('.projectItem').removeClass("projectItemCurrent");	
		}
	}

  });


  // Project View
  // --------------

  // The DOM element for a project...
  window.ProjectView = Backbone.View.extend({

    //... is a div tag.
    tagName:  "div",

    // Cache the template function for a project
    template: _.template($('#project-template').html()),

    // The DOM events specific to a project.
    events: {
    },

    // The ProjectView listens for changes to its model, re-rendering.
    initialize: function() {
    },

    // Render the contents of the projectView.
    render: function() {
      $(this.el).html(this.template(this.model.toJSON()));
	
	//  alert(this.model.get('categories'));
	
      return this;
    }
	
  });


// The Application
  // ---------------

  // Our overall **AppView** is the top-level piece of UI.
  window.AppView = Backbone.View.extend({

    // Instead of generating a new element, bind to the existing skeleton of
    // the App already present in the HTML.
    el: $("#app"),

    // Delegated events
    events: {
		"click #logo":	"goHome"
    },

    // At initialization we bind to the relevant events on the `Categories` and `Projects`
    // collections, when project items are added or changed. Kick things off by
    // loading any preexisting Projects that might be saved in *localStorage*.
    initialize: function() {
      Categories.categoryList.bind('reset', this.addAllCategories, this);
      Categories.categoryList.fetch();
	  Categories.setFirstCurrent();

      Projects.projectList.bind('reset', this.addAllProjectItems, this);
      Projects.projectList.fetch();
	  Projects.setNoCurrent();
    },

    // 
    render: function() {
    },
	
    // Add a single category to the list by creating a view for it, and
    // appending its element.
    addOneCategory: function(i) {
      var view = new CategoryView({model: i});
      this.$("#categories").append(view.render().el);
    },

    // Create category views for all the **Categories** collection at once.
    addAllCategories: function() {
      Categories.categoryList.each(this.addOneCategory);
    },
			

    // Add a single projectItem to the list by creating a view for it, and
    // appending its element.
    addOneProjectItem: function(i) {
      var view = new ProjectItemView({model: i});
      this.$("#projects").append(view.render().el);
    },

    // Create all projectItem views forthe **Projects** collection at once.
    addAllProjectItems: function() {
      Projects.projectList.each(this.addOneProjectItem);
    },
	
	// set the app up to show the passed in category (model)
	showCategory: function(c) {
		
 	  // expand the categories listing
	  $("#projectsBand").removeClass("projectsBandShrunk");
	  
	  // hide the current project
	  $("#currentProject").addClass("dontDisplay");
		
	  Projects.setNoCurrent();

	  Categories.setCurrent(c);

	},
	
	// set the app up to show the passed in project (model)
	showProject: function(p) {
		
	  //  shrink the categories listing
	  $("#projectsBand").addClass("projectsBandShrunk");
	  
	  //  show the  project
	  $("#currentProject").removeClass("dontDisplay");
		
	  Projects.setCurrent(p);

	},
	
	goHome: function() {
		c = Categories.get("currentCategory");
		
		Router.navigate("", true);
	}
	
  });

  // Finally, we kick things off by creating the **App**.
  window.App = new AppView;
  Backbone.history.start({silent: false});
  

});

