/*
 * Copyright (c) 2009, Takeyuki Nagao
 * 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.
 *    
 * 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 COPYRIGHT HOLDER 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.
 */

package dvi.image.split;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;

import javax.imageio.ImageIO;

import dvi.DviException;
import dvi.DviRect;
import dvi.DviRectSplitter;
import dvi.DviResolution;
import dvi.DviSize;
public class DefaultSplitImageWriter implements SplitImageWriter {
//  private static final Logger LOGGER = Logger
//      .getLogger(DefaultSplitImageWriter.class.getName());
  private static class SplitImageImpl implements SplitImage {
    private final DviRectSplitter rectSplitter;
    private final ArrayList<SplitPiece> imagePieces = new ArrayList<SplitPiece>();
    private final DviResolution res;

    public SplitImageImpl(DviResolution res, DviRectSplitter rectSplitter) {
      this.res = res;
      this.rectSplitter = rectSplitter;
    }

    public Collection<SplitPiece> getPieces() throws DviException {
      return Collections.unmodifiableCollection(imagePieces);
    }

    public DviRectSplitter getRectSplitter() throws DviException {
      return rectSplitter;
    }

    public Iterator<SplitPiece> iterator() {
      return imagePieces.iterator();
    }

    public DviRect getRect() throws DviException {
      return rectSplitter.getRect();
    }

    public DviResolution getResolution() {
      return res;
    }
  }
  
  private final File outputFile;
  private final ImageFileConfig imgConf;
  
  protected DviRectSplitter rectSplitter;
  protected SplitImageImpl splitImage;
  private final DviResolution res;

  public DefaultSplitImageWriter(File outputFile, ImageFileConfig imgConf, DviResolution res)
  {
    this.outputFile = outputFile;
    this.imgConf = imgConf;
    this.res = res;
    this.rectSplitter = null;
    this.splitImage = null;
  }
  
  public ImageFileConfig getImageFileConfig() throws DviException {
    return imgConf;
  }

  protected String generateFilename(int rows, int cols, DviSize unit, int row,
      int col) throws DviException
  {
    String filename = getOutputFile().getName() + "-" + res.dpi() + "_" + res.shrinkFactor() + "-"
        + unit.width() + "-" + unit.height() + "-" + rows + "-" + cols + "-"
        + row + "-" + col + getImageFileConfig().getImageExtension();

    return filename;
  }

  public File getOutputFile() {
    return outputFile;
  }


  public void beginSplitImage(ImageSplitter ImageSplitter,
      DviRectSplitter rectSplitter) throws DviException {
    this.rectSplitter = rectSplitter;
    this.splitImage = new SplitImageImpl(getResolution(), rectSplitter);
  }


  public void endSplitImage() throws DviException {
  }

  protected URLImagePiece writeImageToFile(RenderedImage img,
      DviRectSplitter splitter, int row, int col) throws IOException,
      DviException {
    final int rows = splitter.getNumRows();
    final int cols = splitter.getNumColumns();
    final DviSize unit = splitter.getUnitSize();
    String filename = generateFilename(rows, cols, unit, row, col);
    File imgFile = new File(getOutputFile().getParentFile(), filename);
    ImageIO.write(img, imgConf.getImageType(), imgFile);
    return new URLImagePiece(splitImage, imgFile.toURL(), getResolution(), splitter, row, col);
  }

  public void writeImagePiece(RenderedImage img, int row, int col)
      throws DviException {
    try {
      URLImagePiece piece = writeImageToFile(img, rectSplitter, row, col);
      splitImage.imagePieces.add(piece);
    } catch (IOException e) {
      throw new DviException(e);
    }
  }
  
  public SplitImage getSplitImage() throws DviException {
    return splitImage;
  }

  public DviResolution getResolution() {
    return res;
  }
}
