/*
 * Copyright (c) 1999, 2002, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.java2d.loops;

import java.awt.image.BufferedImage;
import java.awt.AlphaComposite;

/**
 * A CompositeType object provides a chained description of a type of
 * algorithm for color compositing.  The object will provide a single
 * String constant descriptor which is one way of describing a particular
 * compositing algorithm as well as a pointer to another CompositeType
 * which describes a more general algorithm for achieving the same result.
 * <p>
 * A description of a more specific algorithm is considered a "subtype"
 * and a description of a more general algorithm is considered a "supertype".
 * Thus, the deriveSubType method provides a way to create a new CompositeType
 * that is related to but more specific than an existing CompositeType and
 * the getSuperType method provides a way to ask a given CompositeType
 * for a more general algorithm to achieve the same result.
 * <p>
 * Note that you cannot construct a brand new root for a chain since
 * the constructor is private.  Every chain of types must at some point
 * derive from the Any node provided here using the deriveSubType()
 * method.  The presence of this common Any node on every chain
 * ensures that all chains end with the DESC_ANY descriptor so that
 * a suitable General GraphicsPrimitive object can be obtained for
 * the indicated algorithm if all of the more specific searches fail.
 */
public final class CompositeType {
    /*
     * CONSTANTS USED BY ALL PRIMITIVES TO DESCRIBE THE COMPOSITING
     * ALGORITHMS THEY CAN PERFORM
     */

    /**
     * algorithm is a general algorithm that uses a CompositeContext
     * to do the rendering.
     */
    public static final String DESC_ANY      = "Any CompositeContext";

    /**
     * constant used to describe the Graphics.setXORMode() algorithm
     */
    public static final String DESC_XOR      = "XOR mode";

    /**
     * constants used to describe the various AlphaComposite
     * algorithms.
     */
    public static final String DESC_CLEAR     = "Porter-Duff Clear";
    public static final String DESC_SRC       = "Porter-Duff Src";
    public static final String DESC_DST       = "Porter-Duff Dst";
    public static final String DESC_SRC_OVER  = "Porter-Duff Src Over Dst";
    public static final String DESC_DST_OVER  = "Porter-Duff Dst Over Src";
    public static final String DESC_SRC_IN    = "Porter-Duff Src In Dst";
    public static final String DESC_DST_IN    = "Porter-Duff Dst In Src";
    public static final String DESC_SRC_OUT   = "Porter-Duff Src HeldOutBy Dst";
    public static final String DESC_DST_OUT   = "Porter-Duff Dst HeldOutBy Src";
    public static final String DESC_SRC_ATOP  = "Porter-Duff Src Atop Dst";
    public static final String DESC_DST_ATOP  = "Porter-Duff Dst Atop Src";
    public static final String DESC_ALPHA_XOR = "Porter-Duff Xor";

    /**
     * constants used to describe the two common cases of
     * AlphaComposite algorithms that are simpler if there
     * is not extraAlpha.
     */
    public static final String
        DESC_SRC_NO_EA      = "Porter-Duff Src, No Extra Alpha";
    public static final String
        DESC_SRC_OVER_NO_EA = "Porter-Duff SrcOverDst, No Extra Alpha";

    /**
     * constant used to describe an algorithm that implements all 8 of
     * the Porter-Duff rules in one Primitive.
     */
    public static final String DESC_ANY_ALPHA = "Any AlphaComposite Rule";

    /*
     * END OF COMPOSITE ALGORITHM TYPE CONSTANTS
     */

    /**
     * The root CompositeType object for all chains of algorithm descriptions.
     */
    public static final CompositeType
        Any           = new CompositeType(null, DESC_ANY);

    /*
     * START OF CompositeeType OBJECTS FOR THE VARIOUS CONSTANTS
     */

    public static final CompositeType
        General       = Any;

    public static final CompositeType
        AnyAlpha      = General.deriveSubType(DESC_ANY_ALPHA);
    public static final CompositeType
        Xor           = General.deriveSubType(DESC_XOR);

    public static final CompositeType
        Clear         = AnyAlpha.deriveSubType(DESC_CLEAR);
    public static final CompositeType
        Src           = AnyAlpha.deriveSubType(DESC_SRC);
    public static final CompositeType
        Dst           = AnyAlpha.deriveSubType(DESC_DST);
    public static final CompositeType
        SrcOver       = AnyAlpha.deriveSubType(DESC_SRC_OVER);
    public static final CompositeType
        DstOver       = AnyAlpha.deriveSubType(DESC_DST_OVER);
    public static final CompositeType
        SrcIn         = AnyAlpha.deriveSubType(DESC_SRC_IN);
    public static final CompositeType
        DstIn         = AnyAlpha.deriveSubType(DESC_DST_IN);
    public static final CompositeType
        SrcOut        = AnyAlpha.deriveSubType(DESC_SRC_OUT);
    public static final CompositeType
        DstOut        = AnyAlpha.deriveSubType(DESC_DST_OUT);
    public static final CompositeType
        SrcAtop       = AnyAlpha.deriveSubType(DESC_SRC_ATOP);
    public static final CompositeType
        DstAtop       = AnyAlpha.deriveSubType(DESC_DST_ATOP);
    public static final CompositeType
        AlphaXor      = AnyAlpha.deriveSubType(DESC_ALPHA_XOR);

    public static final CompositeType
        SrcNoEa       = Src.deriveSubType(DESC_SRC_NO_EA);
    public static final CompositeType
        SrcOverNoEa   = SrcOver.deriveSubType(DESC_SRC_OVER_NO_EA);

    /*
     * END OF CompositeType OBJECTS FOR THE VARIOUS CONSTANTS
     */

    /**
     * Return a new CompositeType object which uses this object as its
     * more general "supertype" descriptor.  If no operation can be
     * found that implements the algorithm described more exactly
     * by desc, then this object will define the more general
     * compositing algorithm that can be used instead.
     */
    public CompositeType deriveSubType(String desc) {
        return new CompositeType(this, desc);
    }

    /**
     * Return a CompositeType object for the specified AlphaComposite
     * rule.
     */
    public static CompositeType forAlphaComposite(AlphaComposite ac) {
        switch (ac.getRule()) {
        case AlphaComposite.CLEAR:
            return Clear;
        case AlphaComposite.SRC:
            if (ac.getAlpha() >= 1.0f) {
                return SrcNoEa;
            } else {
                return Src;
            }
        case AlphaComposite.DST:
            return Dst;
        case AlphaComposite.SRC_OVER:
            if (ac.getAlpha() >= 1.0f) {
                return SrcOverNoEa;
            } else {
                return SrcOver;
            }
        case AlphaComposite.DST_OVER:
            return DstOver;
        case AlphaComposite.SRC_IN:
            return SrcIn;
        case AlphaComposite.DST_IN:
            return DstIn;
        case AlphaComposite.SRC_OUT:
            return SrcOut;
        case AlphaComposite.DST_OUT:
            return DstOut;
        case AlphaComposite.SRC_ATOP:
            return SrcAtop;
        case AlphaComposite.DST_ATOP:
            return DstAtop;
        case AlphaComposite.XOR:
            return AlphaXor;
        default:
            throw new InternalError("Unrecognized alpha rule");
        }
    }

    private static int unusedUID = 1;
    private int uniqueID;
    private String desc;
    private CompositeType next;

    private CompositeType(CompositeType parent, String desc) {
        next = parent;
        this.desc = desc;
        this.uniqueID = makeUniqueID();
    }

    private synchronized static final int makeUniqueID() {
        if (unusedUID > 255) {
            throw new InternalError("composite type id overflow");
        }
        return unusedUID++;
    }

    public int getUniqueID() {
        return uniqueID;
    }

    public String getDescriptor() {
        return desc;
    }

    public CompositeType getSuperType() {
        return next;
    }

    public int hashCode() {
        return desc.hashCode();
    }

    public boolean isDerivedFrom(CompositeType other) {
        CompositeType comptype = this;
        do {
            if (comptype.desc == other.desc) {
                return true;
            }
            comptype = comptype.next;
        } while (comptype != null);
        return false;
    }

    public boolean equals(Object o) {
        if (o instanceof CompositeType) {
            return (((CompositeType) o).uniqueID == this.uniqueID);
        }
        return false;
    }

    public String toString() {
        return desc;
    }
}
