/* JobAttributes.java -- 
   Copyright (C) 2002, 2005  Free Software Foundation, Inc.

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;

/**
 * Needs documentation...
 *
 * @author Eric Blake (ebb9@email.byu.edu)
 * @since 1.3
 * @status updated to 1.4, lacks documentation
 */
public final class JobAttributes implements Cloneable
{
  public static final class DefaultSelectionType extends AttributeValue
  {
    private static final String[] NAMES = { "all", "range", "selection" };
    public static final DefaultSelectionType ALL
      = new DefaultSelectionType(0);
    public static final DefaultSelectionType RANGE
      = new DefaultSelectionType(1);
    public static final DefaultSelectionType SELECTION
      = new DefaultSelectionType(2);
    private DefaultSelectionType(int value)
    {
      super(value, NAMES);
    }
  } // class DefaultSelectionType

  public static final class DestinationType extends AttributeValue
  {
    private static final String[] NAMES = { "file", "printer" };
    public static final DestinationType FILE = new DestinationType(0);
    public static final DestinationType PRINTER = new DestinationType(1);
    private DestinationType(int value)
    {
      super(value, NAMES);
    }
  } // class DestinationType

  public static final class DialogType extends AttributeValue
  {
    private static final String[] NAMES = { "common", "native", "none" };
    public static final DialogType COMMON = new DialogType(0);
    public static final DialogType NATIVE = new DialogType(1);
    public static final DialogType NONE = new DialogType(2);
    private DialogType(int value)
    {
      super(value, NAMES);
    }
  } // class DialogType

  public static final class MultipleDocumentHandlingType
    extends AttributeValue
  {
    private static final String[] NAMES = {
      "separate-documents-collated-copies",
      "separate-documents-uncollated-copies"
    };
    public static final MultipleDocumentHandlingType
      SEPARATE_DOCUMENTS_COLLATED_COPIES
      = new MultipleDocumentHandlingType(0);
    public static final MultipleDocumentHandlingType
      SEPARATE_DOCUMENTS_UNCOLLATED_COPIES
      = new MultipleDocumentHandlingType(1);
    private MultipleDocumentHandlingType(int value)
    {
      super(value, NAMES);
    }
  } // class MultipleDocumentHandlingType

  public static final class SidesType extends AttributeValue
  {
    private static final String[] NAMES
      = { "one-sided", "two-sided-long-edge", "two-sided-short-edge" };
    public static final SidesType ONE_SIDED = new SidesType(0);
    public static final SidesType TWO_SIDED_LONG_EDGE = new SidesType(1);
    public static final SidesType TWO_SIDED_SHORT_EDGE = new SidesType(2);
    private SidesType(int value)
    {
      super(value, NAMES);
    }
  } // class SidesType

  private int copies;
  private DefaultSelectionType selection;
  private DestinationType destination;
  private DialogType dialog;
  private String filename;
  private int maxPage;
  private int minPage;
  private MultipleDocumentHandlingType multiple;
  private int[][] pageRanges; // null for default value
  private int fromPage; // 0 for default value
  private int toPage; // 0 for default value
  private String printer;
  private SidesType sides;

  public JobAttributes()
  {
    copies = 1;
    selection = DefaultSelectionType.ALL;
    destination = DestinationType.PRINTER;
    dialog = DialogType.NATIVE;
    maxPage = Integer.MAX_VALUE;
    minPage = 1;
    multiple
      = MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES;
    sides = SidesType.ONE_SIDED;
  }

  public JobAttributes(JobAttributes attr)
  {
    set(attr);
  }

  public JobAttributes(int copies, DefaultSelectionType selection,
                       DestinationType destination, DialogType dialog,
                       String filename, int max, int min,
                       MultipleDocumentHandlingType multiple,
                       int[][] pageRanges, String printer, SidesType sides)
  {
    if (copies <= 0 || selection == null || destination == null
        || dialog == null || max < min || min <= 0 || multiple == null
        || sides == null)
      throw new IllegalArgumentException();
    this.copies = copies;
    this.selection = selection;
    this.destination = destination;
    this.dialog = dialog;
    this.filename = filename;
    maxPage = max;
    minPage = min;
    this.multiple = multiple;
    setPageRanges(pageRanges);
    this.printer = printer;
    this.sides = sides;
  }

  public Object clone()
  {
    return new JobAttributes(this);
  }

  public void set(JobAttributes attr)
  {
    copies = attr.copies;
    selection = attr.selection;
    destination = attr.destination;
    dialog = attr.dialog;
    filename = attr.filename;
    maxPage = attr.maxPage;
    minPage = attr.minPage;
    multiple = attr.multiple;
    pageRanges = (int[][]) attr.pageRanges.clone();
    printer = attr.printer;
    sides = attr.sides;
    fromPage = attr.fromPage;
    toPage = attr.toPage;
  }

  public int getCopies()
  {
    return copies;
  }

  public void setCopies(int copies)
  {
    if (copies <= 0)
      throw new IllegalArgumentException();
    this.copies = copies;
  }

  public void setCopiesToDefault()
  {
    copies = 1;
  }

  public DefaultSelectionType getDefaultSelection()
  {
    return selection;
  }

  public void setDefaultSelection(DefaultSelectionType selection)
  {
    if (selection == null)
      throw new IllegalArgumentException();
    this.selection = selection;
  }

  public DestinationType getDestination()
  {
    return destination;
  }

  public void setDestination(DestinationType destination)
  {
    if (destination == null)
      throw new IllegalArgumentException();
    this.destination = destination;
  }

  public DialogType getDialog()
  {
    return dialog;
  }

  public void setDialog(DialogType dialog)
  {
    if (dialog == null)
      throw new IllegalArgumentException();
    this.dialog = dialog;
  }

  public String getFileName()
  {
    return filename;
  }

  public void setFileName(String filename)
  {
    this.filename = filename;
  }

  public int getFromPage()
  {
    return fromPage != 0 ? fromPage
      : pageRanges != null ? pageRanges[0][0]
      : toPage != 0 ? toPage : minPage;
  }

  public void setFromPage(int fromPage)
  {
    if (fromPage < minPage || (fromPage > toPage && toPage != 0)
        || fromPage > maxPage)
      throw new IllegalArgumentException();
    if (pageRanges == null)
      this.fromPage = fromPage;
  }

  public int getMaxPage()
  {
    return maxPage;
  }

  public void setMaxPage(int maxPage)
  {
    if (maxPage < minPage)
      throw new IllegalArgumentException();
    this.maxPage = maxPage;
    if (maxPage < fromPage)
      fromPage = maxPage;
    if (maxPage < toPage)
      toPage = maxPage;
    if (pageRanges != null)
      {
        int i = pageRanges.length - 1;
        while (i >= 0 && maxPage < pageRanges[i][1])
          i--;
        if (maxPage >= pageRanges[++i][0])
          pageRanges[i++][1] = maxPage;
        if (i == 0)
          pageRanges = null;
        else if (i < pageRanges.length)
          {
            int[][] tmp = new int[i][];
            System.arraycopy(pageRanges, 0, tmp, 0, i);
            pageRanges = tmp;
          }
      }
  }

  public int getMinPage()
  {
    return minPage;
  }

  public void setMinPage(int minPage)
  {
    if (minPage <= 0 || minPage > maxPage)
      throw new IllegalArgumentException();
    this.minPage = minPage;
    if (minPage > toPage)
      toPage = minPage;
    if (minPage > fromPage)
      fromPage = minPage;
    if (pageRanges != null)
      {
        int size = pageRanges.length;
        int i = 0;
        while (i < size && minPage > pageRanges[i][0])
          i++;
        if (minPage <= pageRanges[i - 1][1])
          pageRanges[--i][0] = minPage;
        if (i == size)
          pageRanges = null;
        else if (i > 0)
          {
            int[][] tmp = new int[size - i][];
            System.arraycopy(pageRanges, i, tmp, 0, size - i);
            pageRanges = tmp;
          }
      }
  }

  public MultipleDocumentHandlingType getMultipleDocumentHandling()
  {
    return multiple;
  }

  public void setMultipleDocumentHandling
    (MultipleDocumentHandlingType multiple)
  {
    if (multiple == null)
      throw new IllegalArgumentException();
    this.multiple = multiple;
  }

  public void setMultipleDocumentHandlingToDefault()
  {
    multiple
      = MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES;
  }

  public int[][] getPageRanges()
  {
    if (pageRanges == null)
      return new int[][] { { getFromPage(), getToPage() } };
    // Perform a deep clone, so user code cannot affect original arrays.
    int i = pageRanges.length;
    int[][] result = new int[i][];
    while (--i >= 0)
      result[i] = (int[]) pageRanges[i].clone();
    return result;
  }

  public void setPageRanges(int[][] pageRanges)
  {
    int size = pageRanges == null ? 0 : pageRanges.length;
    if (size == 0)
      throw new IllegalArgumentException();
    while (--size >= 0)
      {
        int[] range = pageRanges[size];
        if (range == null || range.length != 2
            || range[0] < minPage || range[1] < range[0] || range[1] > maxPage
            || (size != 0 && range[0] <= pageRanges[size - 1][1]))
          throw new IllegalArgumentException();
      }
    size = pageRanges.length;
    if (fromPage > 0 && pageRanges[0][0] > fromPage)
      fromPage = pageRanges[0][0];
    if (toPage > 0 && pageRanges[size - 1][1] < toPage)
      toPage = pageRanges[size - 1][1];
    this.pageRanges = new int[size][];
    while (--size >= 0)
      this.pageRanges[size] = (int[]) pageRanges[size].clone();
  }

  public String getPrinter()
  {
    return printer;
  }

  public void setPrinter(String printer)
  {
    this.printer = printer;
  }

  public SidesType getSides()
  {
    return sides;
  }

  public void setSides(SidesType sides)
  {
    if (sides == null)
      throw new IllegalArgumentException();
    this.sides = sides;
  }

  public void setSidesToDefault()
  {
    sides = SidesType.ONE_SIDED;
  }

  public int getToPage()
  {
    return toPage != 0 ? toPage
      : pageRanges != null ? pageRanges[pageRanges.length - 1][1]
      : fromPage != 0 ? fromPage : maxPage;
  }

  public void setToPage(int toPage)
  {
    if (toPage < minPage || (fromPage > toPage && fromPage != 0)
        || toPage > maxPage)
      throw new IllegalArgumentException();
    if (pageRanges == null)
      this.toPage = toPage;
  }

  public boolean equals(Object o)
  {
    if (this == o)
      return true;
    if (! (o instanceof JobAttributes))
      return false;
    JobAttributes ja = (JobAttributes) o;
    if (copies != ja.copies || selection != ja.selection
        || destination != ja.destination || dialog != ja.dialog
        || ! filename.equals(ja.filename) || maxPage != ja.maxPage
        || minPage != ja.minPage || multiple != ja.multiple
        || fromPage != ja.fromPage || toPage != ja.toPage
        || ! printer.equals(ja.printer) || sides != ja.sides
        || (pageRanges == null) != (ja.pageRanges == null))
      return false;
    if (pageRanges != ja.pageRanges)
      for (int i = pageRanges.length; --i >= 0; )
        if (pageRanges[i][0] != ja.pageRanges[i][0]
            || pageRanges[i][1] != ja.pageRanges[i][1])
          return false;
    return true;
  }

  public int hashCode()
  {
    int hash = (selection.value << 6) ^ (destination.value << 5)
      ^ (dialog.value << 3) ^ (multiple.value << 2) ^ sides.value
      ^ (filename == null ? 0 : filename.hashCode())
      ^ (printer == null ? 0 : printer.hashCode());
    // The effect of the above fields on the hashcode match the JDK. However,
    // I am unable to reverse engineer the effect of the fields listed below,
    // so I am using my own implementation. Note that this still satisfies
    // the general contract of hashcode, it just doesn't match the JDK.
    hash ^= (copies << 27) ^ (maxPage << 22) ^ (minPage << 17);
    if (pageRanges == null)
      hash ^= (getFromPage() << 13) ^ (getToPage() << 8);
    else
      for (int i = pageRanges.length; --i >= 0; )
        hash ^= (pageRanges[i][0] << 13) ^ (pageRanges[i][1] << 8);
    return hash;
  }

  public String toString()
  {
    StringBuffer s = new StringBuffer("copies=").append(copies)
      .append(",defaultSelection=").append(selection).append(",destination=")
      .append(destination).append(",dialog=").append(dialog)
      .append(",fileName=").append(filename).append(",fromPage=")
      .append(getFromPage()).append(",maxPage=").append(maxPage)
      .append(",minPage=").append(minPage)
      .append(",multiple-document-handling=").append(multiple)
      .append(",page-ranges=[");
    if (pageRanges == null)
      s.append(minPage).append(':').append(minPage).append(']');
    else
      for (int i = 0; i < pageRanges.length; i++)
        s.append(pageRanges[i][0]).append(':').append(pageRanges[i][1])
          .append(',');
    s.setLength(s.length() - 1);
    return s.append("],printer=").append(printer).append(",sides=")
      .append(sides).append(",toPage=").append(getToPage()).toString();
  }
} // class JobAttributes
