package com.ibm.able.examples.rules;

//====================================================================
//
// Licensed Materials - Property of IBM
//
// "Restricted Materials of IBM"
//
// Product: com.ibm.able.examples.rules
//
// (C) Copyright IBM Corp. 2001 All Rights Reserved.
//
// US Government Users Restricted Rights - Use, duplication or
// disclosure restricted by GSA ADP Schedule Contract with
// IBM Corp.
//
//
//                             DISCLAIMER
//                             ----------
//
// This material contains programming source code for your consideration.
// These examples have not been thoroughly tested under all conditions.
// IBM, therefore, cannot guarantee or imply reliability, serviceability,
// performance or function of these programs.  All programs contained
// herein are provided to you "AS IS".  THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
// DISCLAIMED.
//
//====================================================================

//====================================================================
// Imports
//====================================================================
import java.io.Serializable;
import java.util.Vector;

import com.ibm.able.Able;

/**
 * A grocery bag has an id, and contains items sized small, medium, or large.
 * @version  $Revision: 1.6 $, $Date: 2001/09/27 20:59:15 $
 */
public class GroceryBag implements Serializable {

   /**
    * Serialized version identifier in form       YYYYMMDDVerRelModxx
    */
   static final long serialVersionUID = 2001100500100300000L;
   private static int nextId = 0;
   private Vector contents = new Vector();
   // protected so ruleset can use object.member notation instead of bulkier object.getMember()
   protected int id = -1;
   protected int numSmallItems = 0;
   protected int numMediumItems = 0;
   protected int numLargeItems = 0;
   private boolean full = false;
   private static double[] countLimitsBySize = new double[]{6,12,18}; 
 
   public GroceryBag() {
      id = nextId++;
   }

   public void addItem(Grocery item) {
      contents.add(item); // add the item to this bag
      item.setBag(id); // show item has been bagged and is now unavailable
      if (item.getSize().equals("large"))
         numLargeItems++;
      else if (item.getSize().equals("medium"))
         numMediumItems++;
      else if (item.getSize().equals("small"))
         numSmallItems++;
      setFull();
   }

   private void setFull() {
       if (getSpaceUsed(new int[]{0,0,0}) >= 1.0) {
         full = true;
      } else {
         full = false;
      }
   }
   private double getSpaceUsed(int[]additionalItems) {
       return (numLargeItems + additionalItems[0]) / countLimitsBySize[0] +
       (numMediumItems + additionalItems[1]) / countLimitsBySize[1] +
       (numSmallItems + additionalItems[2]) / countLimitsBySize[2];      
   }
   public void removeItem(Grocery item) {
      if (contents.contains(item)) {
         contents.remove(item);
         if (item.getSize().equals("large"))
            numLargeItems--;
         else if (item.getSize().equals("medium"))
            numMediumItems--;
         else if (item.getSize().equals("small"))
            numSmallItems--;
         setFull();
      }
   }

   public Vector getContents() {
      return contents;
   }

   public int getNumLargeItems() {
      return numLargeItems;
   }

   public int getNumMediumItems() {
      return numMediumItems;
   }

   public int getNumItems() {
      return contents.size();
   }

   public int getId() {
      return id;
   }

   /**
    * Check to see if there is room for a new item.
    * @param newItemSize The size of the new item.
    * @return true if the bag has space for the new item.
    * Return false if there is no room for the new item.
    */
   public boolean hasSpace(String newItemSize) {
       double spaceUsed;
       if ("small".equals(newItemSize)) spaceUsed = getSpaceUsed(new int[]{0,0,1});
       else if ("medium".equals(newItemSize)) spaceUsed = getSpaceUsed(new int[]{0,1,0});
       else spaceUsed = getSpaceUsed(new int[]{1,0,0});
       return spaceUsed <= 1.0;
   }
   
   public static void reset() {
      nextId = 0;
   }

   public String toString() {
       String filled = full ? "is full" : "is not full";
       double size = getSpaceUsed(new int[]{0,0,0});
       filled += (size == 1.0)?"":"("+size+")";
       return "bag id=" + id +" "+ filled + "; contains "+
                 numSmallItems + "S+"+ numMediumItems + "M+"+ numLargeItems + "L="+ 
                 contents.size()+" groceries=" + contentsAsString() ;
   } 
   
   // specially format contents to avoid having commas ...  screws up Eclipse debugger 
   protected String contentsAsString() {
   	   StringBuffer lclBuf = new StringBuffer();
   	   for (int i=0 ; i < contents.size(); i++) {
   	   	 lclBuf.append(contents.get(i).toString() + " ; " );
   	   }
   	   return lclBuf.toString();
   }
   
   /**
           * Determine the copyright of this class.
           *
           * @return    A String containing this class's copyright statement.
           *            <p>
           */
   private static String Copyright() {
      return Able.Copyright;
   }
}
