/*
 * 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 jp.sourceforge.dvibrowser.dvicore.render;

import jp.sourceforge.dvibrowser.dvicore.DviByteRange;
import jp.sourceforge.dvibrowser.dvicore.DviException;
import jp.sourceforge.dvibrowser.dvicore.DviRect;
import jp.sourceforge.dvibrowser.dvicore.DviResolution;
import jp.sourceforge.dvibrowser.dvicore.api.BinaryDevice;
import jp.sourceforge.dvibrowser.dvicore.api.DviContextSupport;
import jp.sourceforge.dvibrowser.dvicore.api.DviExecutorContext;
import jp.sourceforge.dvibrowser.dvicore.api.DviFont;
import jp.sourceforge.dvibrowser.dvicore.api.Glyph;
import jp.sourceforge.dvibrowser.dvicore.font.LogicalFont;

public class ByteRangeComputer
extends DefaultDevicePainter
{
  private DviByteRange range = DviByteRange.EMPTY;
  private final DviRect rect;
  private final BinaryDevice out;
  private DviRect bbox = DviRect.EMPTY;
  private DviResolution res;

  public ByteRangeComputer(DviContextSupport dcs, DviResolution res, DviRect rect)
  throws DviException
  {
    super(dcs);
    this.rect = rect;
    this.res = res;
    out = new EmptyBinaryDevice(res);
    setOutput(out);
  }

  public DviByteRange getByteRange()
  {
    return range;
  }

  public DviRect getBounds()
  {
    return bbox;
  }

  protected void realDrawChar(LogicalFont lf, int code)
  throws DviException
  {
    DviFont font = getFont();
    if (font != null) {
      Glyph glyph = font.getGlyph(lf, code);
      if (glyph != null) {
        shipOutBOX(
          glyph.bounds().translate(out.getReferencePoint())
        );
      }
    }
  }

  protected void realDrawRule(int w, int h)
  throws DviException
  {
    shipOutBOX(
      new DviRect(0, 0, w, h).translate(out.getReferencePoint())
    );
  }

  private void shipOutBOX(DviRect box)
  throws DviException
  {
    if (box.intersects(rect)) {
      bbox = bbox.union(box);
      DviExecutorContext ctx = getGeometerContext().getExecuterContext();
      range = range.union(
        ctx.getCommandRange()
      );
    }
  }

  public void drawSpecial(byte [] _xxx)
  throws DviException
  {
    // ignored.
  }

  public DviResolution getResolution() {
	return res;
  }
}
