/*$$
 * packages uchicago.src.*
 * Copyright (c) 1999, Trustees of the University of Chicago
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with 
 * or without modification, are permitted provided that the following 
 * conditions are met:
 *
 *	 Redistributions of source code must retain the above copyright notice,
 *	 this list of conditions and the following disclaimer.
 *
 *	 Redistributions in binary form must reproduce the above copyright notice,
 *	 this list of conditions and the following disclaimer in the documentation
 *	 and/or other materials provided with the distribution.
 *
 *	 Neither the name of the University of Chicago nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Nick Collier
 * nick@src.uchicago.edu
 *
 * packages cern.jet.random.*
 * Copyright (c) 1999 CERN - European Laboratory for Particle
 * Physics. Permission to use, copy, modify, distribute and sell this
 * software and its documentation for any purpose is hereby granted without
 * fee, provided that the above copyright notice appear in all copies
 * and that both that copyright notice and this permission notice appear in
 * supporting documentation. CERN makes no representations about the 
 * suitability of this software for any purpose. It is provided "as is" 
 * without expressed or implied warranty. 
 *
 * Wolfgang Hoschek
 * wolfgang.hoschek@cern.ch
 *$$*/

package WealthModel;

import java.awt.Dimension;

import uchicago.src.sim.space.*;
import uchicago.src.collection.BaseMatrix;

public class WealthSpace {

  // the Wealth space is composed of two tori which track the maximum
  // amount of wealth, and the current value at each x,y coordinate.
  private Object2DTorus currentWealth;
  private Object2DTorus maxWealth;

  // default wealth grow rate and the default maximum wealth
//  private int wealthGrowRate = 1;
  private int wealthGrowRate = 0;
//  private int globalMaxWealth = 4;
  private int globalMaxWealth = 0;
  private Dimension size;


  public WealthSpace(String wealthFile) {

    // constructs the maximum wealth torus using the values in the
    // pgm file, wealthspace.pgm.
    // we get this as a stream so can load it from a jar file.
    // if we didn't need to get this from a jar we could just pass
    // the file name to Object2DTorus.
    java.io.InputStream stream = getClass().getResourceAsStream(wealthFile);
    
    maxWealth = new Object2DTorus(stream, Object2DGrid.PGM_ASCII);

    currentWealth = new Object2DTorus(maxWealth.getSizeX(), maxWealth.getSizeY());

    // sets the current wealth to the maximum wealth.
    BaseMatrix m = maxWealth.getMatrix();
    for (int i = 0; i < m.getNumCols(); i++) {
      for (int j = 0; j < m.getNumRows(); j++) {
        Integer intg = (Integer)m.get(i, j);
        currentWealth.putObjectAt(i, j, new Integer(intg.intValue()));
      }
    }

    size = maxWealth.getSize();
    //System.out.println(size.width + ", " + size.height);
  }

  public Dimension getSize() {
    return size;
  }

  public Object2DGrid getCurrentWealth() {
    return currentWealth;
  }

  // The actual implementation of growback rule G, pg 182 (Appendix B).
  public void updateWealth() {
    int wealthAtSpot;
    int maxWealthAtSpot;

    for (int i = 0; i < size.width; i++) {
      for (int j = 0; j < size.height; j++) {
        wealthAtSpot = ((Integer)currentWealth.getObjectAt(i, j)).intValue();
        maxWealthAtSpot = ((Integer)maxWealth.getObjectAt(i, j)).intValue();

        if (wealthGrowRate == -1) {
          currentWealth.putObjectAt(i, j, new Integer(maxWealthAtSpot));
        } else {
          if (wealthAtSpot != maxWealthAtSpot) {
            if (wealthAtSpot + wealthGrowRate <= maxWealthAtSpot) {
              currentWealth.putObjectAt(i, j, new Integer(wealthAtSpot + wealthGrowRate));
            } else {
              currentWealth.putObjectAt(i, j, new Integer(maxWealthAtSpot));
            }
          }
        }
      }
    }
  }

  // takes all the wealth at this coordinate, leaving no wealth.
  public int takeWealthAt(int x, int y) {
    Integer i = (Integer)currentWealth.getObjectAt(x, y);
    currentWealth.putObjectAt(x, y, new Integer(0));
    return i.intValue();
  }

  // gets the amount of wealth at this x,y coordinate
  public int getWealthAt(int x, int y) {
    Integer i = (Integer)currentWealth.getObjectAt(x, y);
    return i.intValue();
  }

  public int getXSize() {
    return size.width;
  }

  public int getYSize() {
    return size.height;
  }
}
