var Cart = Class.create({
    CLASSDEF: {
        name: 'Cart'
    },
  
  initialize: function Cart_initialize() {
    this.products = [];
    this.productsById = new Hash();
    this.derivedProductsByLinkId = {};
    //this.allProducts = {}; //includes derived products
    this.id = -1;
    this.digitizedAssets = {};
    //this.editing = false;
  },
  
  add: function Cart_add(product) {
    if(product.cp_type == CP_DIGITIZATION) {
      var assetDef = d.assets[product.asset_id];
      if(assetDef == null) {
        log("ERROR: unable to get asset " + product.asset_id + " when adding digitization cart item");
        return;
      }
      this.getDigitization(assetDef).product = product;
      this.derivedProductsByLinkId[product.asset_id] = product;
    } //else {
      this.products.push(product);
      this.productsById[product.id] = product;
    //}
    //this.allProducts[product.id] = product;
  },
  
  getProduct: function Cart_getProduct(id) {
    return this.productsById[id];
  },
  
  setValidProducts: function Cart_setValidProducts(ids) {
    var validProducts = [];
    var validProductsById = {};
    for(var i=0; i < ids.length; i++) {
      var pId = ids[i];
      validProducts.push(this.productsById[pId]);
      validProductsById[pId] = this.productsById[pId];
    }
    this.products = validProducts;
    this.productsById = validProductsById;
  },
  
  getFirstEditableProduct: function Cart_getFirstEditableProduct() {
    for(var i=0; i < this.products.length;i++) {
      if((this.products[i].addedToCart)&&(this.products[i].cp_type!=CP_DIGITIZATION)) {
        return this.products[i];
      }
    }
    return null;
  },
  
  getUnsavedProduct: function Cart_getUnsavedProduct() {
    for(var i=0; i < this.products.length;i++) {
      if((!this.products[i].addedToCart)&&(this.products[i].cp_type!=CP_DIGITIZATION)) {
        return this.products[i];
      }
    }
    return null;
  },
  
  copyProduct: function Cart_copyProduct(id) {
    var product = this.productsById[id];
    var cp = this.getUnsavedProduct();
    if(cp != null) {
      cp.copy(product);
      cp.save(true);
    } else {
      
      var asyncKey = asyncStart("designer_container");
      var self = this;
      var t2 = new Ajax.Request(d.pathPrefix + "/designer/new_product?id=" + product.product.id, {asynchronous:true, evalScripts:true, onComplete: function D_onComplete(response) {
          asyncFinish(asyncKey);
          cp = self.getUnsavedProduct();
          if(cp != null) {
            self.copyProduct(id);
          } else {
            alert("ERROR: No new item was added");
          }
        }
       });
    }
  },
  
  removeProduct: function Cart_removeProduct(id) {
    if(confirm(ml("Are you sure you want to remove this product?"))) {
      var product = this.productsById[id];
      this.productsById[id] = null;
      var idx = this.products.indexOf(product);
      if(idx != null) {
        this.products[idx] = null;
        this.products = this.products.compact();
      }
      var cartRow = $("cart_" + id);
	  var cartOptRow=$("cart_options_"+id);
      if(cartRow != null) {
        cartRow.parentNode.removeChild(cartRow);
		cartOptRow.parentNode.removeChild(cartOptRow);
      }
      var aKey = asyncStart("m_cart_pane");
      var self = this;
      var t1 = new Ajax.Request(d.ajaxUrl(d.pathPrefix + "/designer/remove_product?from=designer&id=" + id), {asynchronous:true, evalScripts:true, 
      onComplete: function Cart_onComplete() { 
        d.notifyCartChanged();
        asyncFinish(aKey); 
        if(d.currentCProduct.id == id) { //we deleted the currently selected product....
          //why was below code existing? it would stop us deselecting the view/area/item....
          //d.currentCView = null;
          //d.currentCViewArea = null;
          var firstProduct = self.getFirstEditableProduct();
          if(firstProduct == null) {
            d.startNewCartItem(d.currentCProduct.product.id, true);
            $("m_cart").className="unselected_tab_hidden";
          } else {    
            d.selectConfiguredProduct(firstProduct.id, true, false);
          }
        /*
        why below? shouldnt i leave be if i didnt delete current product?
        } else if((self.products.length == 0) || (self.products.length==1 && self.getUnsavedProduct() != null)) {
          d.startNewCartItem(d.currentCProduct.product.id, true);
          $("m_cart").className="unselected_tab_hidden";*/
        }
        product.remove();
        self.updateCartPrice();
      
      }});
      
      
      //delete this.allProducts[product.id];
    }
  },
  
  updateCartPrice: function Cart_updateCartPrice(doItems) {
    log("updateCartPrice");
    var total = 0;
    var count = 0;
    for(var i=0; i < this.products.length;i++) {
      var p = this.products[i];
      if(p.addedToCart) {
        total += p.getPrice();
        count++;
        if(doItems) {
          p.updateCartPrice(false);
        }
      }
    }
    if(this.tpEl==null) {
      this.tpEl = $("total_price");
    }
    if(this.tpCEL==null) {
      this.tpCEL = $("cart_total_container");
    }
    log("total price=" + total);
    if(this.tpEl!=null) {
      this.tpEl.innerHTML = d.formatPrice(total);
    }
    if(this.tpCEL!=null) {
      if(count <= 1) {
        this.tpCEL.style.display="none";
      } else {
        this.tpCEL.style.display="";
      }
    }
    log("updateCartPrice Done");
  },
  
  selectCartItem: function Cart_selectCartItem(cProduct) {
    if((d.mode != DESIGNER_MODE_CONFIGURE)&&(d.mode != DESIGNER_MODE_VIEW_CUSTOM_PRODUCT)) {
      for(var i=0; i < this.products.length;i++) {
        var p = this.products[i];
        if(p.addedToCart) {
          if(p == cProduct) {
            $("cart_" + p.id).className="cp_details selected";
			$("cart_options_" + p.id).className="cp_options selected";
          } else {
            $("cart_" + p.id).className="cp_details";
			$("cart_options_" + p.id).className="cp_options";
          }
        }
      }
    }
  },
 
  //the state has been restored of a configured product (cancel edit).. lets rebuild the digitization state from the configured products....
  rollbackProduct: function(configuredProduct) {
    this.digitizedAssets = {};
    for(var i=0; i < this.products.length; i++) {
      var p = this.products[i];
      if(p == configuredProduct) {
        p.doRollBack();
      } else if(p.addedToCart) {
        p.restoreSharedState();
      }
    }
  },

  registerDigitizedAsset: function(item) {
    var digDef = this.getDigitization(item.asset);
    digDef.addItem(item);
    return digDef;
  },
  
  getDigitization: function(asset) {
    var digDef = null;
    if(this.digitizedAssets[asset.id] == null) {
      digDef = new DigitizedAsset(asset);
      this.digitizedAssets[asset.id] = digDef;
    } else {
      digDef = this.digitizedAssets[asset.id];
    }
    if(digDef.product == null) {
      digDef.product = this.derivedProductsByLinkId[asset.id]; 
    }
    return digDef;
  }
});


var DigitizedAsset = Class.create({
  CLASSDEF: {
      name: 'DigitizedAsset'
  },
  
  initialize: function DigitizedAsset_initialize(asset) {
    this.asset = asset;
    this.items = new MapList(this);
    this.product = null;
  },
  
  addItem: function DigitizedAsset_addItem(item) {
    this.items.add(new DigitizedAssetItem(item));
    this.items.resort();
    //if(this.configuredProducts[item.cView.configuredProduct.id] == null) {
     // this.configuredProducts[item.cView.configuredProduct.id] = {};
    //}
    //this.configuredProducts[item.cView.configuredProduct.id][item.id] = item;
    if(this.items.list.length == 2) {
      this.changed(item, DIG_EVENT_PRIMARY); //let the other item know it has a sibling...
      //this.items.list[0].item.refreshDigitizedAsset(DIG_EVENT_PRIMARY); 
    }
  },
  
  removeItem: function DigitizedAsset_removeItem(toDel) {
    this.items.remove(toDel.id);
    if(this.items.list.length == 0) { //last item...
      delete d.cart.digitizedAssets[this.asset.id];
      //remove the cart item
      //save product will do this....
      /*if(this.product != null) {
        var cartRow = $("cart_" + this.product.id);
        if(cartRow != null) {
          cartRow.parentNode.removeChild(cartRow);
        }
      }
      */
    } else {
      for(var i=0; i < this.items.list.length; i++) {
        var item = this.items.list[i];
        item.item.refreshDigitizedAsset(DIG_EVENT_PRIMARY);
      }
    }
  },
  
  //the first use is the primary item...
  primaryItem: function DigitizedAsset_primaryItem() {
    if(this.items.list.length == 0) {
      return null;
    } else {
      return this.items.list[0].item;
    }
  },
  
  changed: function DigitizedAsset_changed(src, event) {
    for(var i=0; i < this.items.list.length; i++) {
      var item = this.items.list[i];
      if(item.item != src) {
        item.item.refreshDigitizedAsset(event);
      }
    }
  }
  
});

var DigitizedAssetItem = Class.create({
  CLASSDEF: {
      name: 'DigitizedAssetItem'
  },
  
  initialize: function DigitizedAssetItem_initialize(item) {
    this.id = item.id;
    this.item = item;
    this.sort_key = [
      item.cView.configuredProduct.cartIndex,
      item.cView.productView.viewIndex,
      item.cViewArea.productArea.areaIndex,
      item.id
    ];
  },
  
  //sort the items by cart order, view order, area order, then order added
  compare: function(other) {
    for(var i=0; i < 4; i++) {
      if(this.sort_key[i] > other.sort_key[i]) {
        return 1;
      } else if(this.sort_key[i] < other.sort_key[i]) {
        return -1;
      }
    }
    return 0;
  }
});

