/*
 * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */


package sun.print;

import javax.print.attribute.EnumSyntax;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaSizeName;
import java.util.ArrayList;

class CustomMediaSizeName extends MediaSizeName {
    private static ArrayList customStringTable = new ArrayList();
    private static ArrayList customEnumTable = new ArrayList();
    private String choiceName;
    private MediaSizeName mediaName;

    private CustomMediaSizeName(int x) {
        super(x);

    }

    private synchronized static int nextValue(String name) {
      customStringTable.add(name);

      return (customStringTable.size()-1);
    }

    public CustomMediaSizeName(String name) {
        super(nextValue(name));
        customEnumTable.add(this);
        choiceName = null;
        mediaName = null;
    }

    public CustomMediaSizeName(String name, String choice,
                               float width, float length) {
        super(nextValue(name));
        choiceName = choice;
        customEnumTable.add(this);
        mediaName = null;
        try {
            mediaName = MediaSize.findMedia(width, length,
                                            MediaSize.INCH);
        } catch (IllegalArgumentException iae) {
        }
    }

    /**
     * Version ID for serialized form.
     */
    private static final long serialVersionUID = 7412807582228043717L;

    /**
     * Returns the command string for this media.
     */
    public String getChoiceName() {
        return choiceName;
    }


    /**
     * Returns matching standard MediaSizeName.
     */
    public MediaSizeName getStandardMedia() {
        return mediaName;
    }


    // moved from RasterPrinterJob
    /**
     * Returns closest matching MediaSizeName among given array of Media
     */
    public static MediaSizeName findMedia(Media[] media, float x, float y,
                                          int units) {


        if (x <= 0.0f || y <= 0.0f || units < 1) {
            throw new IllegalArgumentException("args must be +ve values");
        }

        if (media == null || media.length == 0) {
            throw new IllegalArgumentException("args must have valid array of media");
        }

        int size =0;
        MediaSizeName[] msn = new MediaSizeName[media.length];
        for (int i=0; i<media.length; i++) {
            if (media[i] instanceof MediaSizeName) {
                msn[size++] = (MediaSizeName)media[i];
            }
        }

        if (size == 0) {
            return null;
        }

        int match = 0;

        double ls = x * x + y * y;
        double tmp_ls;
        float []dim;
        float diffx = x;
        float diffy = y;

        for (int i=0; i < size ; i++) {
            MediaSize mediaSize = MediaSize.getMediaSizeForName(msn[i]);
            if (mediaSize == null) {
                continue;
            }
            dim = mediaSize.getSize(units);
            if (x == dim[0] && y == dim[1]) {
                match = i;
                break;
            } else {
                diffx = x - dim[0];
                diffy = y - dim[1];
                tmp_ls = diffx * diffx + diffy * diffy;
                if (tmp_ls < ls) {
                    ls = tmp_ls;
                    match = i;
                }
            }
        }

        return msn[match];
    }

    /**
     * Returns the string table for super class MediaSizeName.
     */
    public  Media[] getSuperEnumTable() {
        return (Media[])super.getEnumValueTable();
    }


    /**
     * Returns the string table for class CustomMediaSizeName.
     */
    protected String[] getStringTable() {
      String[] nameTable = new String[customStringTable.size()];
      return (String[])customStringTable.toArray(nameTable);
    }

    /**
     * Returns the enumeration value table for class CustomMediaSizeName.
     */
    protected EnumSyntax[] getEnumValueTable() {
      MediaSizeName[] enumTable = new MediaSizeName[customEnumTable.size()];
      return (MediaSizeName[])customEnumTable.toArray(enumTable);
    }

}
