/* 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., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 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
