var MI_SHOW_SPEED = 600; //ms
var MI_HIDE_SPEED = 300; //ms

// Menu Item
function MenuItem(title, place_item, id, group_name) {
  this._title = title;
  this._place_item = place_item;
  this._id = id;
  this._children = [];
  this._parent = null;
  this._parents = null;
  this._group = group_name;
  this._is_shown = false;

  //Keep in all menu items array
  if(allMenuItemsByGroup[group_name] == null) {
    allMenuItemsByGroup[group_name] = new Array();
  }
  allMenuItemsByGroup[group_name].push(this);
}

MenuItem.prototype._title = null; //Title for the menu item
MenuItem.prototype._children = null; //Array of MenuItems (optional)
MenuItem.prototype._place_item = null; //Item taken from the place_array (Optional)
MenuItem.prototype._id = null; //Id of the item in the JS file (optional)
MenuItem.prototype._group = null; //The group the menu item belongs to
MenuItem.prototype._parent = null; //menu items parent if it has one
MenuItem.prototype._parents = null; //menu items parent if it has one
MenuItem.prototype._has_mappable = null; //If this menu item contains mappable items
MenuItem.prototype._is_shown = null; 
MenuItem.prototype._distance = '';

MenuItem.prototype.addChild = function(child) {
  this._children.push(child);
  child.setParent(this);
  if(child.getPlaceItem() != null) {
    this._has_mappable = true;
  }
};

MenuItem.prototype.show = function() {
  if(this._is_shown == false) {
    $("#" + this.getIdCode()).show(MI_SHOW_SPEED);
  }
  this._is_shown = true;  
};

MenuItem.prototype.hide = function() {
  if(this._is_shown == true) {
    $("#" + this.getIdCode()).hide(MI_HIDE_SPEED);
  }
  this._is_shown = false;
};

MenuItem.prototype.getTitle = function() {
  return this._title;
};

MenuItem.prototype.getNumChildren = function() {
  return this._children.length;
};

MenuItem.prototype.getNumEndLeavesChildren = function() {
  var num_children = this.getNumChildren();
  var num_child_contents = 0;
  for(var i = 0; i < this.getNumChildren(); i++) {
    num_child_contents += this.getChild(i).getNumEndLeavesChildren();
  }
  if(num_child_contents == 0) {
    return num_children;
  } else {
    return num_child_contents;
  }
};

MenuItem.prototype.getChild = function(index) {
  return this._children[index];
};

MenuItem.prototype.getChildById = function(id) {
  for(var i = 0; i < this._children.length; i++) {
    if(this._children[i].getId() == id) {
      return this._children[i]; 
    }
  }
  return null;
};

MenuItem.prototype.getPlaceItem = function() {
  return this._place_item;
};

MenuItem.prototype.getId = function() {
  return this._id;
};

MenuItem.prototype.getGroup = function() {
  return this._group;
};

MenuItem.prototype.getIdCode = function() {
  return "mi" + this._id + this.getGroup();		
};

MenuItem.prototype.getParent = function() {
  return this._parent;
};

MenuItem.prototype.hasMappable = function() {
  return this._has_mappable;
};

//Add a place item 
MenuItem.prototype.addPlaceId = function(id_str) {
  var place = getPlaceFromId(id_str);
  if(place === null) {
    alert("No place with id " + id_str);
    return;
  }
  this.addChild(new MenuItem(place['name'], place, id_str));
  this._has_mappable = true;
};



MenuItem.prototype.getParents = function() {
  if(this._parents === null) {
    return [];
  }
  return this._parents;
};

MenuItem.prototype.setParent = function(parent) {
  this._parent = parent;	
  this._parents = [];

  var par = parent;
  while(par !== null) {		
    this._parents.push(par);
    par = par.getParent();				
  }
};

MenuItem.prototype.setDistance = function(distance) {
  distance = distance / 1609.344;
  distance = Math.round(distance);
  this._distance = distance + ' mi';
}

MenuItem.prototype.getDistance = function(){
  return this._distance;
}

MenuItem.prototype.setupClickHandler = function() {
  $("#" + this.getIdCode()).bind("click", {id: this.getId(), group: this.getGroup()}, selectMenuItem);
};

MenuItem.prototype.selected = function() {

  if(this.getNumChildren() == 0) {
    showInfoWindow(this._id);
    return;
  }

  //Map each item
  this.mapPlaces();

  $(".menu_item").removeClass("minus");
  $(".menu_item").addClass("plus");

  var hidden_items = getAllMenuItemsInGroup(this.getGroup()).slice();

  //Parents and this item
  var shown_items = this.getParents();
  shown_items.push(this);

  for(var i = 0; i < shown_items.length; i++) {
    $("#" + shown_items[i].getIdCode()).removeClass("plus");
    $("#" + shown_items[i].getIdCode()).addClass("minus");
  }	

  //Check if we've selected the same thing again
  var lastMi = lastSelectedMenuItemByGroup[this.getGroup()];
  if(lastMi != null && lastMi.getId() == this.getId()) {
    return;
  }	

  lastSelectedMenuItemByGroup[this.getGroup()] = this;	

  //Add the children	
  shown_items = shown_items.concat(this._children);

  for(var j = 0; j < shown_items.length; j++) {
    shown_items[j].show();
    removeItemFromArray(hidden_items, shown_items[j]);
  }

  for(var k = 0; k < hidden_items.length; k++) {
      hidden_items[k].hide();
  }
};


MenuItem.prototype.mapPlaces = function() {
  clearBounds();
  if(this.hasMappable()) {
    for(var i = 0; i < this._children.length; i++) {
      var place_item = this.getChild(i).getPlaceItem();
      if(place_item != null) {
          extendBounds(place_item);				
      }			
    }		
    setZoomToBounds();		
  }	
};

//Automatically called by the click handler for the menu item
function selectMenuItem(event) {
  var mi = getMenuItem(event.data.id, event.data.group);
  if(mi != null) {
    mi.selected();
  }
}

//All menu items grouped by group name
var allMenuItemsByGroup = new Array();
var lastSelectedMenuItemByGroup = new Array();

function selectLastSelected(group) {
  var mi = lastSelectedMenuItemByGroup[group];
  clearLastSelected();
  mi.selected();
}

function clearLastSelected(group){
  lastSelectedMenuItemByGroup[group] = null;
}

//Get a menu item from its id
function getMenuItem(id, group) {
  for(var i = 0; i < allMenuItemsByGroup[group].length; i++) {
    if(allMenuItemsByGroup[group][i] != null && allMenuItemsByGroup[group][i].getId() == id) {
      return allMenuItemsByGroup[group][i];
    }
  }
}

function getAllMenuItemsInGroup(group_name) {
  return allMenuItemsByGroup[group_name];
}

function clearAllMenuItemsInGroup(group_name) {
  allMenuItemsByGroup[group_name] = null;
}


//Render a menu item as html
function renderMenuItem(mi, depth, rootContainer) {
  var div_class = "menu_item";
  if(mi.getPlaceItem() != null) {
    div_class = "place_item";
  }

  var text = "<div class=\"" + div_class + " menu_depth_" + depth + "\" + id=\"" + mi.getIdCode() + "\">"; 
  text = text + getSpan("place_name", mi.getTitle());

  if(mi.getPlaceItem() == null) {
    text = text + getSpan("place_count", "[" + mi.getNumEndLeavesChildren() + "]");
  } else {
    text = text + getSpan("place_distance", mi.getDistance());
  }

  text = text + "</div>";

  $(rootContainer).append(text);
  mi.setupClickHandler();
  $("#" + mi.getIdCode()).hide();
}

