/*
 * 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.font;
import java.awt.Font;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Logger;

import dvi.DviException;
import dvi.DviFontSpec;
import dvi.DviResolution;
import dvi.DviUnit;
import dvi.api.DviContextSupport;
import dvi.api.DviFont;

public class AWTDynamicPkFontResolver
extends AbstractDviFontResolver
{
  private static final Logger LOGGER = Logger
      .getLogger(AWTDynamicPkFontResolver.class.getName());

  public AWTDynamicPkFontResolver(DviContextSupport dcs, LogicalFont logicalFont) {
    super(dcs, logicalFont);
  }

  @Override
  public Collection<DviFont> call() throws Exception
  {
    Font rawFont = mapToRawAWTFont(getLogicalFont());
    List<DviFont> list = new ArrayList<DviFont>();
    if (rawFont != null) {
      DviFont font = new AWTDynamicPkFont(getDviContext(), rawFont);
      list.add(font);
    }
    return list;
  }
  
  protected Font mapToRawAWTFont(LogicalFont logicalFont)
  {
    DviFontSpec fs = logicalFont.fontSpec();
    DviResolution res = logicalFont.resolution();
    DviUnit dviUnit = logicalFont.dviUnit();
    String face = mapToRawAWTFontFace(logicalFont);
    if (face != null) {
      LOGGER.fine("Using AWT font face " + face + " to render " + logicalFont);
      final int fontSize = (int) dviUnit.mapToPixelDouble(fs.spaceSize(), res.dpi());
      if ("dvicore-awt-dynamic-pk-font-serif".equals(face)) {
        LOGGER.fine("Using serif for" + logicalFont);
        return new Font("serif", Font.PLAIN, fontSize);
      } else if ("dvicore-awt-dynamic-pk-font-sans-serif".equals(face)) {
        LOGGER.fine("Using sans-serif for" + logicalFont);
        return new Font("sans-serif", Font.PLAIN, fontSize);
      } else {
        LOGGER.fine("No AWT font face to render " + logicalFont);
        return new Font(face, Font.PLAIN, fontSize);
      }
    } else {
      LOGGER.fine("No AWT font face to render " + logicalFont);
    }
    return null;
  }


  protected String mapToRawAWTFontFace(LogicalFont logicalFont)
  {
    return logicalFont.fontSpec().name();
  }

  @Override
  public String getCacheKey()
  {
    LogicalFont spec = getLogicalFont();
    return spec.fontSpec().fontName()
    + "-" + spec.fontSpec().checkSum()
    + "-" + spec.fontSpec().spaceSize()
    + "-" + spec.fontSpec().designSize()
    + "-" + spec.resolution().dpi()
    + "-" + spec.dviUnit()
    ;
  }

  @Override
  protected DviFont createInstanceFromStream(InputStream openStream)
      throws DviException
  {
    throw new UnsupportedOperationException();
  }

  @Override
  protected String mapToDviResourceName(LogicalFont logicalFont)
  {
    throw new UnsupportedOperationException();
  }
}
