/*
 * Copyright (c) 1997, 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.
 */

/*
 * @author Charlton Innovations, Inc.
 */

package sun.java2d.loops;

import sun.java2d.loops.GraphicsPrimitive;
import java.awt.Color;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;

/**
 *   DrawLine
 *   1) draw solid color single width line onto destination surface
 *   2) must accept output area [x, y, dx, dy]
 *      from within the surface description data for clip rect
 */
public class DrawLine extends GraphicsPrimitive
{
    public final static String methodSignature = "DrawLine(...)".toString();

    public final static int primTypeID = makePrimTypeID();

    public static DrawLine locate(SurfaceType srctype,
                                  CompositeType comptype,
                                  SurfaceType dsttype)
    {
        return (DrawLine) GraphicsPrimitiveMgr.locate(primTypeID,
                                                      srctype, comptype, dsttype);
    }

    protected DrawLine(SurfaceType srctype,
                       CompositeType comptype,
                       SurfaceType dsttype)
    {
        super(methodSignature, primTypeID, srctype, comptype, dsttype);
    }

    public DrawLine(long pNativePrim,
                    SurfaceType srctype,
                    CompositeType comptype,
                    SurfaceType dsttype)
    {
        super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype);
    }

    /**
     *   All DrawLine implementors must have this invoker method
     */
    public native void DrawLine(SunGraphics2D sg2d, SurfaceData dest,
                                int x1, int y1, int x2, int y2);

    public GraphicsPrimitive makePrimitive(SurfaceType srctype,
                                           CompositeType comptype,
                                           SurfaceType dsttype)
    {
        // REMIND: use FillSpans or converter object?
        throw new InternalError("DrawLine not implemented for "+
                                srctype+" with "+comptype);
    }

    public GraphicsPrimitive traceWrap() {
        return new TraceDrawLine(this);
    }

    private static class TraceDrawLine extends DrawLine {
        DrawLine target;

        public TraceDrawLine(DrawLine target) {
            super(target.getSourceType(),
                  target.getCompositeType(),
                  target.getDestType());
            this.target = target;
        }

        public GraphicsPrimitive traceWrap() {
            return this;
        }

        public void DrawLine(SunGraphics2D sg2d, SurfaceData dest,
                             int x1, int y1, int x2, int y2)
        {
            tracePrimitive(target);
            target.DrawLine(sg2d, dest, x1, y1, x2, y2);
        }
    }
}
