/*
 * 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.special;
import java.io.File;
import java.net.URL;
import java.util.logging.Logger;

import jp.sourceforge.dvibrowser.dvicore.DviObject;
import jp.sourceforge.dvibrowser.dvicore.DviResolution;
import jp.sourceforge.dvibrowser.dvicore.api.DviContextSupport;
import jp.sourceforge.dvibrowser.dvicore.api.DviDocument;
import jp.sourceforge.dvibrowser.dvicore.api.Geometer;
import jp.sourceforge.dvibrowser.dvicore.api.HasURL;
import jp.sourceforge.dvibrowser.dvicore.gui.swing.ViewSpec;
import jp.sourceforge.dvibrowser.dvicore.render.BasicGeometer;
import jp.sourceforge.dvibrowser.dvicore.render.EmptyBinaryDevice;
import jp.sourceforge.dvibrowser.dvicore.util.DviUtils;
import jp.sourceforge.dvibrowser.dvicore.util.concurrent.Computation;
import jp.sourceforge.dvibrowser.dvicore.util.progress.ProgressItem;


public class EmbeddedPostScriptPreparator
extends DviObject
implements Computation<String, EmbeddedPostScript> {
  private static final Logger LOGGER = Logger.getLogger(EmbeddedPostScriptPreparator.class
      .getName());
  private final DviDocument doc;
  private final ViewSpec viewSpec;
  
  public EmbeddedPostScriptPreparator(DviContextSupport dcs, DviDocument doc, ViewSpec viewSpec)
  {
    super(dcs);
    this.doc = doc;
    this.viewSpec = viewSpec;
  }

  public EmbeddedPostScript call() throws Exception
  {
    if (doc == null) return null;
    final ProgressItem progress = getDviContext().getProgressRecorder().open("extracting EPS data");
    try {
      PostScriptSpecialParser pse = new PostScriptSpecialParser(this);
      if (doc instanceof HasURL) {
        URL url = ((HasURL) doc).getURL();
        if (DviUtils.isFile(url)) {
          File file = new File(url.getPath());
          File dir = file.getParentFile();
          LOGGER.finer("working dir=" + dir);
          pse.setWorkDirectory(dir);
        } else {
          LOGGER.finer("Using default working dir");
        }
      } else {
        LOGGER.finer("No URL is available for doc " + doc);
      }
      pse.getEmbeddedPostScript().add(
          new EmbeddedPostScript.PrologueFile(this, "texc.pro"));
      pse.getEmbeddedPostScript().add(
          new EmbeddedPostScript.PrologueFile(this, "special.pro"));
      // This is a dummy output.
      // Should we change this to use viewSpec instead?
      pse.setOutput(new EmptyBinaryDevice(new DviResolution(600, 4)));

      Geometer gm = new BasicGeometer(this);
      gm.setPainter(pse);
      getDviContext().execute(doc, gm);
      EmbeddedPostScript eps = pse.getEmbeddedPostScript();
      return eps;
    } finally {
      progress.close();
    }
  }

  public String getCacheKey()
  {
    return "EPS--" + doc.getCacheKey();
  }

  public DviDocument getDocument()
  {
    return doc;
  }

  public ViewSpec getViewSpec()
  {
    return viewSpec;
  }
}
