public class MultiDimVector {
    
    private Vector ptr = null;
    private IntVector sizes = null;
    public multiDimVector(){}

    // Called with a vector of Integers
    public multiDimVector(IntVector initialSizes){
	initialize(initialSizes);
    }

    public void initialize(IntVector initialSizes){
	sizes = inititialSizes;	
	int total = 0;
	for(int i = 0; i < sizes.size(); i++)
	    total = total + sizes.intAt(i);
	ptr = new Vector(total);
    }

    public void setCell(IntVector coordinates, Object object){
	int cell = 0;
	for(int i = 0; i < sizes.size(); i++){
	    int fixedSize = 1;
	    for(int j = i + 1; j < sizes.size(); j++)
		fixedSize = fixedSize * sizes.intAt(j);
	    cell = cell + (fixedSize * coordinates.intAt(i));
	}
	ptr.setElementAt(object, cell);
    }

    public Object getCell(IntVector coordinates){
	int cell = 0;
	for(int i = 0; i < sizes.size(); i++){
	    int fixedSize = 1;
	    for(int j = i + 1; j < sizes.size(); j++)
		fixedSize = fixedSize * sizes.intAt(j);
	    cell = cell + (fixedSize * coordinates.intAt(i));
	}
	return(ptr.elementAt(cell));
    }
    
    public void changeDimensionSize(int dimension, int newSize){
	IntVector newSizes = sizes;
	newSizes.setIntAt(newSize, dimension);
	Vector newPtr = null;
	int total = 0;
	for(int i = 0; i < newSizes.size(); i++)
	    total = total + sizes.intAt(i);
	newPtr = new Vector(total);
	for(int i = 0; i < ptr.size(); i++)
	    if(isInDimension(getCoordinates(i, sizes), newSizes))
		newPtr.setElementAt(
				    ptr.elementAt(i), 
				    getIndex(
					     getCoordinates(i, sizes), 
					     newSizes));
    }

    private IntVector getCoordinates(int index, IntVector dimensions){	
	IntVector returnValue = new IntVector(dimensions.size());
	int remains = index;
	for(int i = 0; i < returnValue.size(); i++){
	    returnValue.setIntAt(remains / getIntervalSize(i, dimensions), i);
	    remains = remains % getIntervalSize(i, dimensions);	    
	}
	return(returnValue);
    }

    private int getIndex(IntVector coordinates, IntVector dimensions){
	int returnValue = 0;
	for(int i = 0; i < dimensions.size(); i++)
	    returnValue = 
		returnValue + 
		coordinates.intAt(i) * 
		getIntervalSize(i, dimensions);
	return(returnValue);
    }

    // dimension is zero-indexed
    private int getIntervalSize(int dimension, IntVector dimensions){
	int returnValue = 1;
	for(int i = dimension + 1; i < dimensions.size(); i++)
	    returnValue = returnValue * dimensions.intAt(i);
	return(returnValue);
    }

    private boolean isInDimension(IntVector coordinates, IntVector dimensions){
	for(int i = 0; i < coordinates.size(); i++)
	    if(dimensions.intAt(i) < coordinates.intAt(i))
		return(false);
	return(true);
    }

	
	










