/* Copyright (C) 2000, 2002  Free Software Foundation

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.awt.image;

import gnu.java.awt.Buffers;

/* FIXME: This class does not yet support data type TYPE_SHORT */

/**
 * @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
 */
public class ComponentSampleModel extends SampleModel
{
  protected int[] bandOffsets;
  protected int[] bankIndices;
  
  // FIXME: Should we really shadow the numBands in the superclass?
  //protected int numBands;
  
  /** Used when creating data buffers. */
  protected int numBanks;

  protected int scanlineStride;
  
  protected int pixelStride;
  
  private boolean tightPixelPacking = false;
  
  public ComponentSampleModel(int dataType,
			      int w, int h,
			      int pixelStride,
			      int scanlineStride,
			      int[] bandOffsets)
  {
    this(dataType, w, h, pixelStride, scanlineStride,
	 new int[bandOffsets.length], bandOffsets);
  }
    
  public ComponentSampleModel(int dataType,
			      int w, int h,
			      int pixelStride,
			      int scanlineStride,
			      int[] bankIndices,
			      int[] bandOffsets)
  {
    super(dataType, w, h, bandOffsets.length);
    if ((pixelStride<0) || (scanlineStride<0) || 
	(bandOffsets.length<1) ||
	(bandOffsets.length != bankIndices.length))
      throw new IllegalArgumentException();
    
    this.bandOffsets = bandOffsets;
    this.bankIndices = bankIndices;

    for (int b=0; b<bankIndices.length; b++)
      this.numBanks = Math.max(this.numBanks, bankIndices[b]+1);

    this.scanlineStride = scanlineStride;
    this.pixelStride = pixelStride;

    // See if we can use some speedups

    /* FIXME: May these checks should be reserved for the
       PixelInterleavedSampleModel? */
	
    if (pixelStride == numBands)
      {
	tightPixelPacking = true;
	for (int b=0; b<numBands; b++) {
	  if ((bandOffsets[b] != b) || (bankIndices[b] !=0))
	    {
	      tightPixelPacking = false;
	      break;
	    }
	}
      }
  }		

  public SampleModel createCompatibleSampleModel(int w, int h)
  {
    return new ComponentSampleModel(dataType, w, h, pixelStride,
				    scanlineStride, bankIndices,
				    bandOffsets);
  }

  public SampleModel createSubsetSampleModel(int[] bands)
  {
    int numBands = bands.length;
    
    int[] bankIndices = new int[numBands];
    int[] bandOffsets = new int[numBands];
    for (int b=0; b<numBands; b++)
      {
	bankIndices[b] = this.bankIndices[bands[b]];
	bandOffsets[b] = this.bandOffsets[bands[b]];
      }

    return new ComponentSampleModel(dataType, width, height, pixelStride,
				    scanlineStride, bankIndices,
				    bandOffsets);
  }

  public DataBuffer createDataBuffer()
  {
    // Maybe this value should be precalculated in the constructor?
    int highestOffset = 0;
    for (int b=0; b<numBands; b++)
      {
	highestOffset = Math.max(highestOffset, bandOffsets[b]);
      }
    int size = pixelStride*(width-1) + scanlineStride*(height-1) +
      highestOffset + 1;
    
    return Buffers.createBuffer(getDataType(), size, numBanks);
  }

  public int getOffset(int x, int y)
  {
    return getOffset(x, y, 0);
  }

  public int getOffset(int x, int y, int b)
  {
    return bandOffsets[b] + pixelStride*x + scanlineStride*y;
  }

  public final int[] getSampleSize()
  {
    int size = DataBuffer.getDataTypeSize(getDataType());
    int[] sizes = new int[numBands];

    java.util.Arrays.fill(sizes, size);
    return sizes;
  }

  public final int getSampleSize(int band)
  {
    return DataBuffer.getDataTypeSize(getDataType());
  }

  public final int[] getBankIndices()
  {
    return bankIndices;
  }

  public final int[] getBandOffsets()
  {
    return bandOffsets;
  }

  public final int getScanlineStride()
  {
    return scanlineStride;
  }

  public final int getPixelStride()
  {
    return pixelStride;
  }

  public final int getNumDataElements()
  {
    return numBands;
  }

  public Object getDataElements(int x, int y, Object obj, DataBuffer data)
  {
    int xyOffset = pixelStride*x + scanlineStride*y;
    
    int[] totalBandDataOffsets = new int[numBands];
    
    /* Notice that band and bank offsets are different. Band offsets
       are managed by the sample model, and bank offsets are managed
       by the data buffer. Both must be accounted for. */
    
    /* FIXME: For single pixels, it is probably easier to simple
       call getElem instead of calculating the bank offset ourself.
       
       On the other hand, then we need to push the value through
       the int type returned by the getElem method.  */
    
    int[] bankOffsets = data.getOffsets();
    
    for (int b=0; b<numBands; b++)
      {
	totalBandDataOffsets[b] = 
	  bandOffsets[b]+bankOffsets[bankIndices[b]] + xyOffset;
      }
	
    try
      {
	switch (getTransferType())
	  {
	  case DataBuffer.TYPE_BYTE:
	    DataBufferByte inByte = (DataBufferByte) data;
	    byte[] outByte = (byte[]) obj;
	    if (outByte == null) outByte = new byte[numBands];
		
	    for (int b=0; b<numBands; b++)
	      {
		int dOffset = totalBandDataOffsets[b];
		outByte[b] = inByte.getData(bankIndices[b])[dOffset];
	      }
	    return outByte;
		
	  case DataBuffer.TYPE_USHORT:
	    DataBufferUShort inUShort = (DataBufferUShort) data;
	    short[] outUShort = (short[]) obj;
	    if (outUShort == null) outUShort = new short[numBands];
		
	    for (int b=0; b<numBands; b++)
	      {
		int dOffset = totalBandDataOffsets[b];
		outUShort[b] = inUShort.getData(bankIndices[b])[dOffset];
	      }
	    return outUShort;

	  case DataBuffer.TYPE_INT:
	    DataBufferInt inInt = (DataBufferInt) data;
	    int[] outInt = (int[]) obj;
	    if (outInt == null) outInt = new int[numBands];
		
	    for (int b=0; b<numBands; b++)
	      {
		int dOffset = totalBandDataOffsets[b];
		outInt[b] = inInt.getData(bankIndices[b])[dOffset];
	      }
	    return outInt;
		
	    // FIXME: Fill in the other possible types.
	  default:
	      throw new IllegalStateException("unknown transfer type " +
					      getTransferType());
	  }
      }
    catch (ArrayIndexOutOfBoundsException aioobe)
      {
	String msg = "While reading data elements, " +
	  "x=" + x + ", y=" + y +", " + ", xyOffset=" + xyOffset +
	  ", data.getSize()=" + data.getSize() + ": " + aioobe;
	throw new ArrayIndexOutOfBoundsException(msg);
      }
  }

  public Object getDataElements(int x, int y, int w, int h, Object obj,
				DataBuffer data)
  {
    if (!tightPixelPacking)
      {
	return super.getDataElements(x, y, w, h, obj, data);
      }

    // using get speedup
    
    // We can copy whole rows
    int rowSize = w*numBands;
    int dataSize = rowSize*h;
    
    DataBuffer transferBuffer =
      Buffers.createBuffer(getTransferType(), obj, dataSize);
    obj = Buffers.getData(transferBuffer);

    int inOffset =
      pixelStride*x +
      scanlineStride*y +
      data.getOffset(); // Assumes only one band is used

    /* We don't add band offsets since we assume that bands have
       offsets 0, 1, 2, ... */

    // See if we can copy everything in one go
    if (scanlineStride == rowSize)
      {
	// Collapse scan lines:
	rowSize *= h;
	// We ignore scanlineStride since it won't be of any use
	h = 1;
      }

    int outOffset = 0;
    Object inArray = Buffers.getData(data);
    for (int yd = 0; yd<h; yd++)
      {
	System.arraycopy(inArray, inOffset, obj, outOffset, rowSize);
	inOffset  += scanlineStride;
	outOffset += rowSize;
      }
    return obj;
  }

  public void setDataElements(int x, int y, int w, int h,
			      Object obj, DataBuffer data)
  {
    if (!tightPixelPacking)
      {
	super.setDataElements(x, y, w, h, obj, data);
	return;
      }

    // using set speedup, we can copy whole rows
    int rowSize = w*numBands;
    int dataSize = rowSize*h;
    
    DataBuffer transferBuffer =
      Buffers.createBufferFromData(getTransferType(), obj, dataSize);

    int[] bankOffsets = data.getOffsets();

    int outOffset =
      pixelStride*x +
      scanlineStride*y +
      bankOffsets[0]; // same assuptions as in get...

    // See if we can copy everything in one go
    if (scanlineStride == rowSize)
      {
	// Collapse scan lines:
	scanlineStride = rowSize *= h;
	h = 1;
      }

    int inOffset = 0;
    Object outArray = Buffers.getData(data);
    for (int yd = 0; yd<h; yd++)
      {
	System.arraycopy(obj, inOffset, outArray, outOffset, rowSize);
	outOffset += scanlineStride;
	inOffset  += rowSize;
      }
  }

  public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
  {
    int offset = pixelStride*x + scanlineStride*y;
    if (iArray == null) iArray = new int[numBands];
    for (int b=0; b<numBands; b++)
      {
	iArray[b] = data.getElem(bankIndices[b], offset+bandOffsets[b]);
      }
    return iArray;
  }

  public int[] getPixels(int x, int y, int w, int h, int[] iArray,
			 DataBuffer data)
  {
    int offset = pixelStride*x + scanlineStride*y;
    if (iArray == null) iArray = new int[numBands*w*h];
    int outOffset = 0;
    for (y=0; y<h; y++)
      {
	int lineOffset = offset;
	for (x=0; x<w; x++)
	  {
	    for (int b=0; b<numBands; b++)
	      {
		iArray[outOffset++] = 
		  data.getElem(bankIndices[b], lineOffset+bandOffsets[b]);
	      }
	    lineOffset += pixelStride;
	  }
	offset += scanlineStride;
      }
    return iArray;
  }
    
  public int getSample(int x, int y, int b, DataBuffer data)
  {
    return data.getElem(bankIndices[b], getOffset(x, y, b));
  }

  public void setDataElements(int x, int y, Object obj, DataBuffer data)
  {
    int offset = pixelStride*x + scanlineStride*y;
    int[] totalBandDataOffsets = new int[numBands];
    int[] bankOffsets = data.getOffsets();
    for (int b=0; b<numBands; b++)
      totalBandDataOffsets[b] =
	bandOffsets[b]+bankOffsets[bankIndices[b]] + offset;

    switch (getTransferType())
      {
      case DataBuffer.TYPE_BYTE:
	{
	  DataBufferByte out = (DataBufferByte) data;
	  byte[] in = (byte[]) obj;
	  
	  for (int b=0; b<numBands; b++)
	    out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
	  
	  return;
	}
      case DataBuffer.TYPE_USHORT:
	{
	  DataBufferUShort out = (DataBufferUShort) data;
	  short[] in = (short[]) obj;
	  
	  for (int b=0; b<numBands; b++)
	    out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
	  
	  return;
	}
      case DataBuffer.TYPE_INT:
	{
	  DataBufferInt out = (DataBufferInt) data;
	  int[] in = (int[]) obj;
	  
	  for (int b=0; b<numBands; b++)
	    out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
	  
	  return;
	}
      default:
	throw new UnsupportedOperationException("transfer type not " +
						"implemented");
      }
  }
  
  public void setPixel(int x, int y, int[] iArray, DataBuffer data)
  {
    int offset = pixelStride*x + scanlineStride*y;
    for (int b=0; b<numBands; b++)
      data.setElem(bankIndices[b], offset+bandOffsets[b], iArray[b]);
  }
    
  public void setSample(int x, int y, int b, int s, DataBuffer data)
  {
    data.setElem(bankIndices[b], getOffset(x, y, b), s);
  }
}
