// Rightsizing functions

function pallCap(module, product, it) {
  // Version 0.4 - Martin Arrand 13/08/07 - PRODUCTION
  // Determines capacity of module - i.e. number of products that pack into module
  // module : object containing x,y,z dimensions of module (with those properties), maxWeight
  // product : object containing x,y,z dimensions of product (with those properties), weight
  // it : iteration - if zero then we try to pack residuals, if not then we just make a single pass 

  var i, cap1, cap2, cap3, p = product, weightCap;
  var products=[], capacities=[], residues=[], allowed=[];

  if (it===undefined) {
    it=0;
  }

  // Calculate orientations of product
  products[0] = product;
  products[1] = { x: p.x, y: p.z, z: p.y, weight:p.weight };
  products[2] = { x: p.y, y: p.x, z: p.z, weight:p.weight };
  products[3] = { x: p.y, y: p.z, z: p.x, weight:p.weight };
  products[4] = { x: p.z, y: p.x, z: p.y, weight:p.weight };
  products[5] = { x: p.z, y: p.y, z: p.x, weight:p.weight };

  // Calculate allowed orientations
  allowed[0] = (!p.xx) && (!p.yy) && (!p.zz);
  allowed[1] = (!p.xx) && (!p.yz) && (!p.zy);
  allowed[2] = (!p.yx) && (!p.xy) && (!p.zz);
  allowed[3] = (!p.yx) && (!p.zy) && (!p.xz);
  allowed[4] = (!p.zx) && (!p.xy) && (!p.yz);
  allowed[5] = (!p.zx) && (!p.yy) && (!p.xz);
  
  // Calculate max capacity by weight loading
  if (module.maxWeight && p.weight) {
      weightCap = Math.floor(module.maxWeight/p.weight);
  }
  
  for (i=0; i<6; i++) {
    // Calculate capacities for different orientations
    capacities[i] = {
      x: Math.floor(module.x/products[i].x),
      y: Math.floor(module.y/products[i].y),
      z: Math.floor(module.z/products[i].z)
    };

    capacities[i].cap = allowed[i] ? capacities[i].x * capacities[i].y * capacities[i].z : 0;
    
    // Adjust for maximum weight loadings
    if (weightCap) {
        capacities[i].cap = Math.min(weightCap, capacities[i].cap);
    }

    // Calculate residual volumes
    residues[i] = {
      x: module.x - (products[i].x * capacities[i].x),
      y: module.y - (products[i].y * capacities[i].y),
      z: module.z - (products[i].z * capacities[i].z)
    };
  }
    

  if (it===0) {
    // Find capacities of residual volumes
    for (i=0; i<6; i++) {
      if (allowed[i] && capacities[i].cap!==0) {
        cap1 = pallCap({ x: residues[i].x, y: module.y, z: module.z }, product, 1);
        cap2 = pallCap({ x: module.x, y: residues[i].y, z: module.z }, product, 1);
        cap3 = pallCap({ x: module.x, y: module.y, z: residues[i].z }, product, 1);
        cap1 = Math.max(cap1, cap2, cap3);
        capacities[i].cap = capacities[i].cap + cap1;
      }
    }
  }

  // Return best capacity
  cap1 = capacities[0].cap;
  for (i=1; i<6; i++) {
    if (capacities[i].cap > cap1) {
      cap1 = capacities[i].cap;
    }
  }

  return cap1;
}


