/*
 * 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.afp;

import java.awt.geom.AffineTransform;

import org.apache.fop.fo.Constants;
import org.apache.fop.util.ColorUtil;

/**
 * Handles the drawing of borders/lines in AFP
 */
public class AFPBorderPainter extends AbstractAFPPainter {

    /**
     * Main constructor
     *
     * @param paintingState the AFP painting state converter
     * @param dataStream the AFP datastream
     */
    public AFPBorderPainter(AFPPaintingState paintingState, DataStream dataStream) {
        super(paintingState, dataStream);
    }

    /** {@inheritDoc} */
    public void paint(PaintingInfo paintInfo) {
        BorderPaintingInfo borderPaintInfo = (BorderPaintingInfo)paintInfo;
        float w = borderPaintInfo.getX2() - borderPaintInfo.getX1();
        float h = borderPaintInfo.getY2() - borderPaintInfo.getY1();
        if ((w < 0) || (h < 0)) {
            log.error("Negative extent received. Border won't be painted.");
            return;
        }

        int pageWidth = dataStream.getCurrentPage().getWidth();
        int pageHeight = dataStream.getCurrentPage().getHeight();
        AFPUnitConverter unitConv = paintingState.getUnitConverter();
        AffineTransform at = paintingState.getData().getTransform();

        float x1 = unitConv.pt2units(borderPaintInfo.getX1());
        float y1 = unitConv.pt2units(borderPaintInfo.getY1());
        float x2 = unitConv.pt2units(borderPaintInfo.getX2());
        float y2 = unitConv.pt2units(borderPaintInfo.getY2());

        switch (paintingState.getRotation()) {
        case 0:
            x1 += at.getTranslateX();
            y1 += at.getTranslateY();
            x2 += at.getTranslateX();
            y2 += at.getTranslateY();
            break;
        case 90:
            x1 += at.getTranslateY();
            y1 += (float) (pageWidth - at.getTranslateX());
            x2 += at.getTranslateY();
            y2 += (float) (pageWidth - at.getTranslateX());
            break;
        case 180:
            x1 += (float) (pageWidth - at.getTranslateX());
            y1 += (float) (pageHeight - at.getTranslateY());
            x2 += (float) (pageWidth - at.getTranslateX());
            y2 += (float) (pageHeight - at.getTranslateY());
            break;
        case 270:
            x1 = (float) (pageHeight - at.getTranslateY());
            y1 += (float) at.getTranslateX();
            x2 += x1;
            y2 += (float) at.getTranslateX();
            break;
        }

        AFPLineDataInfo lineDataInfo = new AFPLineDataInfo();
        lineDataInfo.setColor(borderPaintInfo.getColor());
        lineDataInfo.setRotation(paintingState.getRotation());
        lineDataInfo.x1 = Math.round(x1);
        lineDataInfo.y1 = Math.round(y1);
        if (borderPaintInfo.isHorizontal()) {
            lineDataInfo.setThickness(Math.round(y2 - y1));
        } else {
            lineDataInfo.setThickness(Math.round(x2 - x1));
        }

        // handle border-*-style
        switch (borderPaintInfo.getStyle()) {
        case Constants.EN_DOUBLE:
            if (borderPaintInfo.isHorizontal()) {
                lineDataInfo.x2 = Math.round(x2);
                lineDataInfo.y2 = lineDataInfo.y1;
                dataStream.createLine(lineDataInfo);
                lineDataInfo.y1 += Math.round((lineDataInfo.thickness / 3) * 2);
                dataStream.createLine(lineDataInfo);
            } else {
                lineDataInfo.x2 = lineDataInfo.x1;
                lineDataInfo.y2 = Math.round(y2);
                dataStream.createLine(lineDataInfo);
                lineDataInfo.x1 += Math.round((lineDataInfo.thickness / 3) * 2);
                dataStream.createLine(lineDataInfo);
            }
            break;
        case Constants.EN_DASHED:
            int thick = lineDataInfo.thickness * 3;
            if (borderPaintInfo.isHorizontal()) {
                lineDataInfo.x2 = lineDataInfo.x1 + thick;
                lineDataInfo.y2 = lineDataInfo.y1;
                int ex2 = Math.round(x2);
                while (lineDataInfo.x1 + thick < ex2) {
                    dataStream.createLine(lineDataInfo);
                    lineDataInfo.x1 += 2 * thick;
                    lineDataInfo.x2 = lineDataInfo.x1 + thick;
                }
            } else {
                lineDataInfo.x2 = lineDataInfo.x1;
                lineDataInfo.y2 = lineDataInfo.y1 + thick;
                int ey2 = Math.round(y2);
                while (lineDataInfo.y1 + thick < ey2) {
                    dataStream.createLine(lineDataInfo);
                    lineDataInfo.y1 += 2 * thick;
                    lineDataInfo.y2 = lineDataInfo.y1 + thick;
                }
            }
            break;
        case Constants.EN_DOTTED:
            if (borderPaintInfo.isHorizontal()) {
                lineDataInfo.x2 = lineDataInfo.x1 + lineDataInfo.thickness;
                lineDataInfo.y2 = lineDataInfo.y1;
                int ex2 = Math.round(x2);
                while (lineDataInfo.x1 + lineDataInfo.thickness < ex2) {
                    dataStream.createLine(lineDataInfo);
                    lineDataInfo.x1 += 3 * lineDataInfo.thickness;
                    lineDataInfo.x2 = lineDataInfo.x1 + lineDataInfo.thickness;
                }
            } else {
                lineDataInfo.x2 = lineDataInfo.x1;
                lineDataInfo.y2 = lineDataInfo.y1 + lineDataInfo.thickness;
                int ey2 = Math.round(y2);
                while (lineDataInfo.y1 + lineDataInfo.thickness < ey2) {
                    dataStream.createLine(lineDataInfo);
                    lineDataInfo.y1 += 3 * lineDataInfo.thickness;
                    lineDataInfo.y2 = lineDataInfo.y1 + lineDataInfo.thickness;
                }
            }
            break;
        case Constants.EN_GROOVE:
        case Constants.EN_RIDGE:
            //TODO
            lineDataInfo.x2 = Math.round(x2);
            float colFactor = (borderPaintInfo.getStyle() == Constants.EN_GROOVE ? 0.4f : -0.4f);
            float h3 = (y2 - y1) / 3;
            lineDataInfo.color = ColorUtil.lightenColor(borderPaintInfo.getColor(), -colFactor);
            lineDataInfo.thickness = Math.round(h3);
            lineDataInfo.y1 = lineDataInfo.y2 = Math.round(y1);
            dataStream.createLine(lineDataInfo);
            lineDataInfo.color = borderPaintInfo.getColor();
            lineDataInfo.y1 = lineDataInfo.y2 = Math.round(y1 + h3);
            dataStream.createLine(lineDataInfo);
            lineDataInfo.color = ColorUtil.lightenColor(borderPaintInfo.getColor(), colFactor);
            lineDataInfo.y1 = lineDataInfo.y2 = Math.round(y1 + h3 + h3);
            dataStream.createLine(lineDataInfo);
            break;
        case Constants.EN_HIDDEN:
            break;
        case Constants.EN_INSET:
        case Constants.EN_OUTSET:
        case Constants.EN_SOLID:
        default:
            if (borderPaintInfo.isHorizontal()) {
                lineDataInfo.x2 = Math.round(x2);
                lineDataInfo.y2 = lineDataInfo.y1;
            } else {
                lineDataInfo.x2 = lineDataInfo.x1;
                lineDataInfo.y2 = Math.round(y2);
            }
            dataStream.createLine(lineDataInfo);
        }
    }

}
