var TeamNames = Class.create({
  CLASSDEF: {
      name:  'TeamNames'
  },
  
  initialize: function TeamNames_initialize(configuredProduct) {
    this.configuredProduct = configuredProduct;
    this.names = new MapList(this);
    this.items = {};
    this.nextId = 1;
    this.selectedTeamName = null;
  },
  
  registerTeamNameItem: function TeamNames_registerTeamNameItem(teamNameItem) {
    this.items[teamNameItem.id] = teamNameItem;
  },
  
  unregisterTeamNameItem: function TeamNames_unregisterTeamNameItem(teamNameItem) {
    delete this.items[teamNameItem.id]
    if(hashFirstElement(this.items) == null) {
      this.configuredProduct.usingTeamnames = false;
      var hasSizes = (this.configuredProduct.product.type.sizeField != null);
      if(hasSizes) {
        var sizeField = this.configuredProduct.getSelectedSize();
        sizeField.reloadHtml();
      }
      this.configuredProduct.product.type.updatePrice();
    }
  },
  
  getNextId: function TeamNames_getNextId() {
    return this.nextId++;
  },
  
  load: function TeamNames_load(params) {
    for(var i=0; i < params.length; i++) {
      var nameParam = params[i];
      nameParam.id = this.getNextId();
      this.names.add(new TeamName(nameParam, this));
    }
    if((this.selectedTeamName == null)&&(this.names.list.length > 0)) {
      this.selectedTeamName = this.names.list[0];
    }
  },
  
  initNew: function TeamNames_initNew(newTeamNameItem) {
    this.newTeamNameItem = newTeamNameItem;
    this.loadTeamNameIds();
    var existingGroups = this.groupNamesBySizes();
    
    if(this.configuredProduct.product.type.sizeField != null) {
      var sizeField = this.configuredProduct.getSelectedSize();
      
      for(var i=0; i < sizeField.productField.options.list.length; i++) {
        var pOpt = sizeField.productField.options.list[i];
        if(!pOpt.def.isMulti) {
          if(pOpt.subs != null) {
            for(var k in pOpt.subs) {
              var pSub = pOpt.subs[k];
              var el = $('tn_mqs_' + pSub.id);
              var val = 0;
              if(el != null) {
                val = parseInt(el.value ,10);
                this.addTeamNames(val, pOpt.id, pSub.id, existingGroups);
              } else {
                log("Missing multi qty el for sub option " + pSub.id);
              }
              
            }
          } else {
            var el = $('tn_mq_' + pOpt.id);
            var val = 0;
            if(el != null) {
              val = parseInt(el.value ,10);
              this.addTeamNames(val, pOpt.id, null, existingGroups);
            } else {
              log("Missing multi qty el for option " + pOpt.id);
            }
          }
        }
      }
    } else {
      //just 1 qty...
      var qty = parseInt($("tn_qty").value, 10);
      this.addTeamNames(qty, null, null, existingGroups);
    }
    //remove any existing that are no longer used....
    for(var k in existingGroups) {
      var group = existingGroups[k];
      for(var i=0; i < group.length; i++) {
        this.removeMember(group[i].id, true);
      }
    }
    
    if(this.tmpNames.list.length == 0) {
      return false;
    }
    
    if((this.tmpSelectedTeamName == null)&&(this.tmpNames.list.length > 0)) {
      this.tmpSelectedTeamName = this.tmpNames.list[0];
    }

    $("teamname_edit_container").update(this.renderHtml());
    
    
    return true;
  },
  
  groupNamesBySizes: function TeamNames_groupNamesBySizes() {
    var grouping = {};
    for(var i=0; i < this.names.list.length; i++) {
      var name = this.names.list[i];
      var id = name.selectedId();
      if(grouping[id] == null) {
        grouping[id] = [];
      }
      grouping[id].push(name);
    }
    return grouping;
  },
  
  editTeamNames: function TeamNames_editTeamNames() {
    this.loadTeamNameIds();
    $("teamname_edit_container").update(this.renderHtml());
    popup('edit_teamname_popup');
  },
  
  //we keep a temp list of teamname ids so we know whats available to save when save is clicked.. means cancel has to do nothing
  loadTeamNameIds: function TeamNames_loadTeamNameIds() {
    this.tmpNames = this.names.clone();
    if((this.selectedTeamName == null)&&(this.names.list.length > 0)) {
      this.selectedTeamName = this.names.list[0];
    }
    this.tmpSelectedTeamName = this.selectedTeamName; //tmp var in case cancel is clicked...
  },
  
  cancelNew: function TeamNames_cancelNew() {
    if(this.newTeamNameItem != null) {
      this.newTeamNameItem.del();
      //this.unregisterTeamNameItem(this.newTeamNameItem);
      this.newTeamNameItem = null;
    }
  },
  
  //from init new
  addTeamNames: function TeamNames_addTeamNames(qty, optionId, subOptionId, existingGroups) {
    if(existingGroups != null) {
      var id = optionId;
      if(subOptionId) {
        id += "-" + this.subOptionId;
      }
      var existingGroup = existingGroups[id];
      if(existingGroup != null) {
        log("Found existing group:" + id);
        qty -= existingGroup.length;
        if(qty < 0) { //we need to remove some...
          existingGroup.reverse(); //take from end of list....
          while(qty < 0) {
            var toDel = existingGroup.pop();
            log("Removing existing group member:" + toDel.id);
            this.removeMember(toDel.id, true);
            qty ++;
          }
        }
        delete existingGroups[id]; //track which were used....
      }
    }
    
    for(var i=0; i < qty; i++) {
      this.tmpNames.add(new TeamName({id : this.getNextId(), o: optionId, s: subOptionId}, this));
    }
  },
  
  //from interface button 
  addMember: function TeamNames_addMember() {
    var options = null;
    var hasSizes = (this.configuredProduct.product.type.sizeField != null);
    
    if(hasSizes) {
      options = this.configuredProduct.product.type.sizeField.getOptionList(this.configuredProduct, this.configuredProduct.product.getSizeField(), this.configuredProduct.getSelectedSize(), this.configuredProduct.product.sizeColorCombinations, false);
    }
    
    var views = this.getItemsByAreas();
    var name = new TeamName({id : this.getNextId(), o: null, s: null}, this);
    this.tmpNames.add(name);

    var rowHtml = this.renderNameHtml(name, hasSizes,options,views, (this.tmpNames.list.length == 1));
    new Insertion.Bottom("tn_names_tbody", rowHtml);
  },
  
  //from interface button 
  removeMember: function TeamNames_removeMember(id, dontReselect) {
    if((this.tmpNames.list.length == 1)&&(dontReselect != true)) {
      alert(ml("You cannot remove the last teamname. If you do not want to use teamnames remove the teamname item from your design."));
      return;
    }
    var wasSelected = (this.tmpSelectedTeamName == this.tmpNames.byId[id]);
    this.tmpNames.remove(id);
    $('tn_' + id + '_row').remove();
    if(wasSelected && dontReselect) {
      this.tmpSelectedTeamName = null;
      this.selectedTeamName = null;
    } else if(wasSelected && this.tmpNames.list.length > 0) {
      this.tmpSelectedTeamName = this.tmpNames.list[0];
      $('tn_v_' + this.tmpSelectedTeamName.id).checked = true;
    }
  },
  
  //from UI
  saveTeamNames: function TeamNames_saveTeamNames() {
    if(this.tmpNames.list.length == 0) {
      alert(ml("You must have defined at least one teamname"));
      return;
    }
    this.saveTeamNamesFromUI();
    this.updateConfiguredProductFromTeamNames();
    d.track("save-teamnames");
    this.configuredProduct.setQtyFromMulti();
    this.configuredProduct.product.type.updatePrice();
    this.selectedTeamName = this.tmpSelectedTeamName;
    this.updateTeamNameItems();
    d.itemChanged();
  },
  
  //save from form elements back into data model
  saveTeamNamesFromUI: function TeamNames_saveTeamNamesFromUI() {
    if(this.newTeamNameItem != null) {
      this.newTeamNameItem = null;
    }
    var hasSizes = (this.configuredProduct.product.type.sizeField != null);

    var sizeField = hasSizes ? this.configuredProduct.getSelectedSize() : null;
    var views = this.getItemsByAreas();
    
    for(var i =0; i < this.tmpNames.list.length; i++) {
      this.tmpNames.list[i].clear();
    }
    this.names = this.tmpNames;
    for(var x =0; x < this.tmpNames.list.length; x++) {
      var name = this.tmpNames.list[x];
      if(hasSizes) {
        var sizeSelection = $F('tn_size_' + name.id);
        var ids = sizeField.extractOptIds(sizeSelection);
        name.optionId = ids[0];
        name.subOptionId = ids[1];
      }
                
      for(var i=0; i < views.length; i++) {
        var view = views[i];
        for(var j=0; j < view.areas.length; j++) {
          var area = view.areas[j];
          for(var k=0; k < area.items.length; k++) {
            var item = area.items[k];
            for(var l=0; l< item.teamNameTemplate.config.sections.length; l++) {
              var section = item.teamNameTemplate.config.sections[l];
              var nameData = $F('tn_' + name.id + '_' + item.id + '_' + l);
              name.setCellData(item.id, l, nameData);
            }
          }
        }
      }
    }
  },
  
  //update the size/qty of the configured product to match the config of the teamnames,,,
  updateConfiguredProductFromTeamNames: function TeamNames_updateConfiguredProductFromTeamNames() {
    var hasSizes = (this.configuredProduct.product.type.sizeField != null);
    this.configuredProduct.usingTeamnames = true;
    if(hasSizes) {
      var sizeField = this.configuredProduct.getSelectedSize();
      var productSizeField = this.configuredProduct.product.getSizeField();
      if(productSizeField.multiOption == null) {
        log("dynamically adding multiple sizes option to product to support teamnames");
        productSizeField.addMultiOption();
      }
      sizeField.setSelectedOption(productSizeField.multiOption.id, 1, null, true);
      
      //group by option selections...
      var sizeGrouping = {};
      for(var i=0; i < this.names.list.length; i++) {
        var name = this.names.list[i];
        var key = name.selectedId();
        if(sizeGrouping[key] == null) {
          sizeGrouping[key] = {qty: 0, optionId: name.optionId, subOptionId: name.subOptionId};
        }
        sizeGrouping[key].qty +=1;
      }
      for(var k in sizeGrouping) {
        var grouping = sizeGrouping[k];
        sizeField.addSelectedOption(grouping.optionId, grouping.qty, grouping.subOptionId);
      }
      sizeField.reloadHtml();
    } else {
      this.configuredProduct.qty = this.names.list.length;
    }
    
  },
  
  updateTeamNameItems: function TeamNames_updateTeamNameItems() {
    for(var k in this.items) {
      var item = this.items[k];
      item.setText(false, 2);
    }
    
  },
  
  renderHtml: function TeamNames_renderHtml() {
    var options = null;
    var hasSizes = (this.configuredProduct.product.type.sizeField != null);
    
    if(hasSizes) {
      options = this.configuredProduct.product.type.sizeField.getOptionList(this.configuredProduct, this.configuredProduct.product.getSizeField(), this.configuredProduct.getSelectedSize(), this.configuredProduct.product.sizeColorCombinations, false);
    }
    
    var views = this.getItemsByAreas();
    
    var cells = [];
    var rows = [];
    var useViewName = views.length > 1 ? true : false;
    if(hasSizes) {
      cells.push('<th>&nbsp</th>');
    }
    for(var i=0; i < views.length; i++) {
      var view = views[i];
      var useAreaName = view.areas.length > 1 ? true : false;
      for(var j=0; j < view.areas.length; j++) {
        var area = view.areas[j];
        var locationLabel = "";
        if(useViewName) {
          locationLabel = view.view.name;
          if(useAreaName) {
            locationLabel += " " + area.area.name;
          }
          locationLabel = " (" + locationLabel + ")";
        } else if(useAreaName) {
          locationLabel += " (" + area.area.name + ")";
        }
        for(var k=0; k < area.items.length; k++) {
          var item = area.items[k];
          for(var l=0; l< item.teamNameTemplate.config.sections.length; l++) {
            var section = item.teamNameTemplate.config.sections[l];
            var sName = (section.name == null) ? "Name " + (l+1) : section.name;
            sName += locationLabel;
            cells.push('<th>' + sName + '</th>');
          }
        }
      }
    }
    cells.push('<th>view</th>');
    cells.push('<th>remove</th>');
    header = '<tr>' + cells.join('') + '</tr>';
    
    for(var x=0; x < this.tmpNames.list.length; x++) {
      var name = this.tmpNames.list[x];
      
      rows.push('<tr>' + this.renderNameHtml(name, hasSizes,options,views, (this.names.list.length==1 || this.selectedTeamName==name) ) + '</tr>');
    }
    return "<table class='base hundred'>" + header + '<tbody id="tn_names_tbody">' + rows.join("\n") + "</tbody></table>";
  },
  
  renderNameHtml: function TeamNames_renderNameHtml(name, hasSizes,options,views, isSelected) {
    cells = [];
    if(hasSizes) {
      cells.push('<td><select id="tn_size_' + name.id + '">' + selectOptionHtml(options, name.selectedId() ) + '</select></td>');
    }
    for(var i=0; i < views.length; i++) {
      var view = views[i];
      for(var j=0; j < view.areas.length; j++) {
        var area = view.areas[j];
        for(var k=0; k < area.items.length; k++) {
          var item = area.items[k];
          for(var l=0; l< item.teamNameTemplate.config.sections.length; l++) {
            var section = item.teamNameTemplate.config.sections[l];
            var cellData = name.getCellData(item.id, l);
            if(cellData == null) cellData = "";
            cells.push('<td><input type="text" id="tn_' + name.id + '_' + item.id + '_' + l + '" value="' + cellData + '" size="15"/></td>');
          }
        }
      }
    }
    var selHtml = isSelected ? ' checked="true"' : '';
    cells.push('<td><input type="radio" id="tn_v_' + name.id + '" name="tn_view"' + selHtml + ' onclick="d.currentCProduct.getTeamNames().view(' + name.id + ');"/></td>');
    cells.push('<td><a href="#" onclick="d.currentCProduct.getTeamNames().removeMember(' + name.id + '); return false;" class="icon delete">delete</a></td>');
    return '<tr id="tn_' + name.id + '_row">' + cells.join('') + '</tr>';
  },
  
  getItemsByAreas: function TeamNames_getItemsByAreas() {
    var byViews = {};
    for(var k in this.items) {
      var item = this.items[k];
      if(byViews[item.cView.id] == null) {
        byViews[item.cView.id] = {};
      }
      if(byViews[item.cView.id][item.cViewArea.id] == null) {
        byViews[item.cView.id][item.cViewArea.id] = [];
      }
      byViews[item.cView.id][item.cViewArea.id].push(item);
    }
    
    var views = [];
    //we want these in the same order as what is defined in the product...
    for(var i=0; i < this.configuredProduct.product.views.list.length; i++) {
      var view = this.configuredProduct.product.views.list[i];
      if(byViews[view.id] != null) {
        var viewData = {view: view, areas:[]};
        for(var j=0; j < view.areas.list.length; j++) {
          var area = view.areas.list[j];
          if(byViews[view.id][area.id] != null) {
            viewData.areas.push({area:area, items: byViews[view.id][area.id]});
          }
        }
        views.push(viewData);
      }
    }
    return views;
  },
  
  view: function TeamNames_view(id) {
    this.tmpSelectedTeamName = this.tmpNames.byId[id];
  },
  
  serialize: function TeamNames_serialize(queryComponents, prefix) {
    for(var i=0; i < this.names.list.length; i++) {
      this.names.list[i].serialize(queryComponents, prefix + "[" + i + "]");
    }
  },
  
  serializeToOptions: function TeamNames_serializeToOptions() {
    var o = {};
    for(var i=0; i < this.names.list.length; i++) {
      o[i] = this.names.list[i].serializeToOptions();
    }
    return o;
  }
  
  
});


var TeamName = Class.create({
  CLASSDEF: {
      name:  'TeamName'
  },
  
  initialize: function TeamName_initialize(config, teamNames) {
    this.id = config.id;
    this.optionId = config.o;
    this.subOptionId = config.s;
    this.names = { names:config.n};
    this.teamNames = teamNames;
    if(this.names == null) this.names = {};
    if(this.names.names == null) this.names.names = {};
  },
  
  selectedId: function TeamName_selectedId() {
    if(this.subOptionId != null) {
      return this.optionId + "-" + this.subOptionId;
    } else {
      return this.optionId;
    }
  },
  
  clear: function() {
    this.names.names = {};
  },
  
  getCellData: function TeamName_getCellData(item_id, sectionIdx) {
    return this.names.names[item_id + '_' + sectionIdx];
  },
  
  setCellData: function TeamName_setCellData(item_id, sectionIdx, value) {
    this.names.names[item_id + '_' + sectionIdx] = value;
  },
  
  serialize: function TeamName_serialize(queryComponents, prefix) {
    if(this.optionId != null) {
      queryComponents.push(encodeURIComponent(prefix + "[o]") + "=" + encodeURIComponent(this.optionId));
    }
    if(this.subOptionId != null) {
      queryComponents.push(encodeURIComponent(prefix + "[s]") + "=" + encodeURIComponent(this.subOptionId));
    }
    for(var k in this.names.names) {
      queryComponents.push(encodeURIComponent(prefix + "[n][" + k + "]") + "=" + encodeURIComponent(this.names.names[k]));
    }
  },
  
  serializeToOptions: function TeamName_serializeToOptions() {
    var o = {};
    if(this.optionId != null) {
      o.o = this.optionId;
    }
    if(this.subOptionId != null) {
      o.s = this.subOptionId;
    }
    var names = {}; 
    for(var k in this.names.names) {
      names.k = this.names.names[k];
    }
    o.n = names;
    return o;
  }
});
