/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

package org.apache.fop.render.intermediate;

import java.awt.Color;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.IOException;

import org.apache.fop.traits.BorderProps;
import org.apache.fop.traits.RuleStyle;

/**
 * This is an abstract base class for handling border painting.
 */
public abstract class BorderPainter {

    /**
     * Draws borders.
     * @param borderRect the border rectangle
     * @param bpsTop the border specification on the top side
     * @param bpsBottom the border specification on the bottom side
     * @param bpsLeft the border specification on the left side
     * @param bpsRight the border specification on the end side
     * @throws IOException if an I/O error occurs while creating the borders
     */
    public void drawBorders(Rectangle borderRect,               // CSOK: MethodLength
            BorderProps bpsTop, BorderProps bpsBottom,
            BorderProps bpsLeft, BorderProps bpsRight) throws IOException {
        int startx = borderRect.x;
        int starty = borderRect.y;
        int width = borderRect.width;
        int height = borderRect.height;
        boolean[] b = new boolean[] {
            (bpsTop != null), (bpsRight != null),
            (bpsBottom != null), (bpsLeft != null)};
        if (!b[0] && !b[1] && !b[2] && !b[3]) {
            return;
        }
        int[] bw = new int[] {
            (b[0] ? bpsTop.width : 0),
            (b[1] ? bpsRight.width : 0),
            (b[2] ? bpsBottom.width : 0),
            (b[3] ? bpsLeft.width : 0)};
        int[] clipw = new int[] {
            BorderProps.getClippedWidth(bpsTop),
            BorderProps.getClippedWidth(bpsRight),
            BorderProps.getClippedWidth(bpsBottom),
            BorderProps.getClippedWidth(bpsLeft)};
        starty += clipw[0];
        height -= clipw[0];
        height -= clipw[2];
        startx += clipw[3];
        width -= clipw[3];
        width -= clipw[1];

        boolean[] slant = new boolean[] {
            (b[3] && b[0]), (b[0] && b[1]), (b[1] && b[2]), (b[2] && b[3])};
        if (bpsTop != null) {
            int sx1 = startx;
            int sx2 = (slant[0] ? sx1 + bw[3] - clipw[3] : sx1);
            int ex1 = startx + width;
            int ex2 = (slant[1] ? ex1 - bw[1] + clipw[1] : ex1);
            int outery = starty - clipw[0];
            int clipy = outery + clipw[0];
            int innery = outery + bw[0];

            saveGraphicsState();
            moveTo(sx1, clipy);
            int sx1a = sx1;
            int ex1a = ex1;
            if (bpsTop.mode == BorderProps.COLLAPSE_OUTER) {
                if (bpsLeft != null && bpsLeft.mode == BorderProps.COLLAPSE_OUTER) {
                    sx1a -= clipw[3];
                }
                if (bpsRight != null && bpsRight.mode == BorderProps.COLLAPSE_OUTER) {
                    ex1a += clipw[1];
                }
                lineTo(sx1a, outery);
                lineTo(ex1a, outery);
            }
            lineTo(ex1, clipy);
            lineTo(ex2, innery);
            lineTo(sx2, innery);
            closePath();
            clip();
            drawBorderLine(sx1a, outery, ex1a, innery, true, true,
                    bpsTop.style, bpsTop.color);
            restoreGraphicsState();
        }
        if (bpsRight != null) {
            int sy1 = starty;
            int sy2 = (slant[1] ? sy1 + bw[0] - clipw[0] : sy1);
            int ey1 = starty + height;
            int ey2 = (slant[2] ? ey1 - bw[2] + clipw[2] : ey1);
            int outerx = startx + width + clipw[1];
            int clipx = outerx - clipw[1];
            int innerx = outerx - bw[1];

            saveGraphicsState();
            moveTo(clipx, sy1);
            int sy1a = sy1;
            int ey1a = ey1;
            if (bpsRight.mode == BorderProps.COLLAPSE_OUTER) {
                if (bpsTop != null && bpsTop.mode == BorderProps.COLLAPSE_OUTER) {
                    sy1a -= clipw[0];
                }
                if (bpsBottom != null && bpsBottom.mode == BorderProps.COLLAPSE_OUTER) {
                    ey1a += clipw[2];
                }
                lineTo(outerx, sy1a);
                lineTo(outerx, ey1a);
            }
            lineTo(clipx, ey1);
            lineTo(innerx, ey2);
            lineTo(innerx, sy2);
            closePath();
            clip();
            drawBorderLine(innerx, sy1a, outerx, ey1a, false, false,
                           bpsRight.style, bpsRight.color);
            restoreGraphicsState();
        }
        if (bpsBottom != null) {
            int sx1 = startx;
            int sx2 = (slant[3] ? sx1 + bw[3] - clipw[3] : sx1);
            int ex1 = startx + width;
            int ex2 = (slant[2] ? ex1 - bw[1] + clipw[1] : ex1);
            int outery = starty + height + clipw[2];
            int clipy = outery - clipw[2];
            int innery = outery - bw[2];

            saveGraphicsState();
            moveTo(ex1, clipy);
            int sx1a = sx1;
            int ex1a = ex1;
            if (bpsBottom.mode == BorderProps.COLLAPSE_OUTER) {
                if (bpsLeft != null && bpsLeft.mode == BorderProps.COLLAPSE_OUTER) {
                    sx1a -= clipw[3];
                }
                if (bpsRight != null && bpsRight.mode == BorderProps.COLLAPSE_OUTER) {
                    ex1a += clipw[1];
                }
                lineTo(ex1a, outery);
                lineTo(sx1a, outery);
            }
            lineTo(sx1, clipy);
            lineTo(sx2, innery);
            lineTo(ex2, innery);
            closePath();
            clip();
            drawBorderLine(sx1a, innery, ex1a, outery, true, false,
                           bpsBottom.style, bpsBottom.color);
            restoreGraphicsState();
        }
        if (bpsLeft != null) {
            int sy1 = starty;
            int sy2 = (slant[0] ? sy1 + bw[0] - clipw[0] : sy1);
            int ey1 = sy1 + height;
            int ey2 = (slant[3] ? ey1 - bw[2] + clipw[2] : ey1);
            int outerx = startx - clipw[3];
            int clipx = outerx + clipw[3];
            int innerx = outerx + bw[3];

            saveGraphicsState();
            moveTo(clipx, ey1);
            int sy1a = sy1;
            int ey1a = ey1;
            if (bpsLeft.mode == BorderProps.COLLAPSE_OUTER) {
                if (bpsTop != null && bpsTop.mode == BorderProps.COLLAPSE_OUTER) {
                    sy1a -= clipw[0];
                }
                if (bpsBottom != null && bpsBottom.mode == BorderProps.COLLAPSE_OUTER) {
                    ey1a += clipw[2];
                }
                lineTo(outerx, ey1a);
                lineTo(outerx, sy1a);
            }
            lineTo(clipx, sy1);
            lineTo(innerx, sy2);
            lineTo(innerx, ey2);
            closePath();
            clip();
            drawBorderLine(outerx, sy1a, innerx, ey1a, false, true, bpsLeft.style, bpsLeft.color);
            restoreGraphicsState();
        }
    }


    /**
     * Draws a border line.
     * @param x1 X coordinate of the upper left corner
     *                  of the line's bounding rectangle (in millipoints)
     * @param y1 start Y coordinate of the upper left corner
     *                  of the line's bounding rectangle (in millipoints)
     * @param x2 end X coordinate of the lower right corner
     *                  of the line's bounding rectangle (in millipoints)
     * @param y2 end y coordinate of the lower right corner
     *                  of the line's bounding rectangle (in millipoints)
     * @param horz true if it is a horizontal line
     * @param startOrBefore true if the line is the start or end edge of a border box
     * @param style the border style
     * @param color the border color
     * @throws IOException if an I/O error occurs
     */
    protected abstract void drawBorderLine(                      // CSOK: ParameterNumber
            int x1, int y1, int x2, int y2,
            boolean horz, boolean startOrBefore, int style, Color color) throws IOException;

    /**
     * Draws a line/rule.
     * @param start start point (coordinates in millipoints)
     * @param end end point (coordinates in millipoints)
     * @param width width of the line
     * @param color the line color
     * @param style the rule style
     * @throws IOException if an I/O error occurs
     */
    public abstract void drawLine(Point start, Point end,
            int width, Color color, RuleStyle style) throws IOException;

    /**
     * Moves the cursor to the given coordinate.
     * @param x the X coordinate (in millipoints)
     * @param y the Y coordinate (in millipoints)
     * @throws IOException if an I/O error occurs
     */
    protected abstract void moveTo(int x, int y) throws IOException;

    /**
     * Draws a line from the current cursor position to the given coordinates.
     * @param x the X coordinate (in millipoints)
     * @param y the Y coordinate (in millipoints)
     * @throws IOException if an I/O error occurs
     */
    protected abstract void lineTo(int x, int y) throws IOException;

    /**
     * Closes the current path.
     * @throws IOException if an I/O error occurs
     */
    protected abstract void closePath() throws IOException;

    /**
     * Reduces the current clipping region to the current path.
     * @throws IOException if an I/O error occurs
     */
    protected abstract void clip() throws IOException;

    /**
     * Save the graphics state on the stack.
     * @throws IOException if an I/O error occurs
     */
    protected abstract void saveGraphicsState() throws IOException;

    /**
     * Restore the last graphics state from the stack.
     * @throws IOException if an I/O error occurs
     */
    protected abstract void restoreGraphicsState() throws IOException;

}
