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

import java.awt.Color;
import java.io.Serializable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fo.expr.PropertyException;
import org.apache.fop.util.ColorUtil;

/**
 * Border properties.
 * Class to store border trait properties for the area tree.
 */
public class BorderProps implements Serializable {

    private static final long serialVersionUID = 8022237892391068187L;

    public enum Mode {
        SEPARATE("separate") {
            @Override
            int getClippedWidth(BorderProps bp) {
                return 0;
            }
        },
        COLLAPSE_INNER("collapse-inner"), // for borders inside a table
        COLLAPSE_OUTER("collapse-outer"); // for borders at the table's outer border

        private final String value;

        Mode(String value) {
            this.value = value;
        }

        int getClippedWidth(BorderProps bp) {
            return bp.width / 2;
        };
    }

    /** Border style (one of EN_*) */
    public final int style; // Enum for border style
    /** Border color */
    public final Color color;

    /** Border width */
    public final int width;

    private final int radiusStart;

    private final int radiusEnd;

    /** Border mode */
    private final Mode mode;

    /**
     * Constructs a new BorderProps instance.
     * @param style border style (one of EN_*)
     * @param width border width
     * @param radiusStart radius of start corner in the direction perpendicular to border segment
     * @param radiusEnd radius of end corner in the direction perpendicular to border segment
     * @param color border color
     * @param mode border mode ((one of SEPARATE, COLLAPSE_INNER and COLLAPSE_OUTER)
     */
    public BorderProps(int style, int width, int radiusStart, int radiusEnd, Color color, Mode mode) {
        this.style = style;
        this.width = width;
        this.radiusStart = radiusStart;
        this.radiusEnd = radiusEnd;
        this.color = color;
        this.mode = mode;
    }

    /**
     * Factory method for a new BorderProps instance with rectangular corners.
     * @param style border style (one of EN_*)
     * @param width border width
     * @param color border color
     * @param mode border mode ((one of SEPARATE, COLLAPSE_INNER and COLLAPSE_OUTER)
     */
    public static BorderProps makeRectangular(int style, int width, Color color, Mode mode) {
        return new BorderProps(style, width, 0, 0, color, mode);
    }

    private BorderProps(String style, int width, int radiusStart, int radiusEnd, Color color, Mode mode) {
        this(getConstantForStyle(style), width, radiusStart, radiusEnd, color, mode);
    }

    /**
     *
     * @return the radius of the corner adjacent to the before or start border
     */
    public int getRadiusStart() {
        return radiusStart;
    }

    /**
     * @return the radius of the corner adjacent to the after or end border
     */
    public int getRadiusEnd() {
        return radiusEnd;
    }

    /**
     * @return the border mode ((one of SEPARATE, COLLAPSE_INNER and COLLAPSE_OUTER)
     */
    public Mode getMode() {
        return mode;
    }

    /**
     * @param bp the border properties or null
     * @return the effective width of the clipped part of the border
     */
    public static int getClippedWidth(BorderProps bp) {
        return bp == null ? 0 : bp.mode.getClippedWidth(bp);
    }

    private String getStyleString() {
        return BorderStyle.valueOf(style).getName();
    }

    private static int getConstantForStyle(String style) {
        return BorderStyle.valueOf(style).getEnumValue();
    }

    public boolean isCollapseOuter() {
        return mode == Mode.COLLAPSE_OUTER;
    }

    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        return toString().hashCode();
    }

    /** {@inheritDoc} */
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        } else if (obj == this) {
            return true;
        } else {
            if (obj instanceof BorderProps) {
                BorderProps other = (BorderProps) obj;
                return (style == other.style)
                        && org.apache.xmlgraphics.java2d.color.ColorUtil.isSameColor(
                                color, other.color)
                        && width == other.width
                        && mode == other.mode
                        && radiusStart == other.radiusStart
                        && radiusEnd == other.radiusEnd;
            }
        }
        return false;
    }

    /**
     * Returns a BorderProps represtation of a string of the format as written by
     * BorderProps.toString().
     * @param foUserAgent FOP user agent caching ICC profiles
     * @param s the string
     * @return a BorderProps instance
     */
    public static BorderProps valueOf(FOUserAgent foUserAgent, String s) {
        return BorderPropsDeserializer.INSTANCE.valueOf(foUserAgent, s);
    }
    /** {@inheritDoc} */
    @Override
    public String toString() {
        StringBuffer sbuf = new StringBuffer();
        sbuf.append('(')
                .append(getStyleString()).append(',')
                .append(ColorUtil.colorToString(color)).append(',')
                .append(width);
        if (!mode.equals(Mode.SEPARATE)) {
            sbuf.append(",").append(mode.value);
        }

        if (radiusStart != 0 || radiusEnd != 0) {
            if (mode.equals(Mode.SEPARATE)) {
                // Because of the corner radii properties the mode must be set
                // so that the parameter index is consistent
                sbuf.append(",").append(Mode.SEPARATE.value);
            }
            sbuf.append(',').append(radiusStart)
            .append(',').append(radiusEnd);
        }
        sbuf.append(')');
        return sbuf.toString();
    }

    private static final class BorderPropsDeserializer {

        private static final BorderPropsDeserializer INSTANCE = new BorderPropsDeserializer();

        private static final Pattern PATTERN = Pattern.compile("([^,\\(]+(?:\\(.*\\))?)");

        private BorderPropsDeserializer() {
        }

        public BorderProps valueOf(FOUserAgent foUserAgent, String s) {
            if (s.startsWith("(") && s.endsWith(")")) {
                s = s.substring(1, s.length() - 1);
                Matcher m = PATTERN.matcher(s);
                m.find();
                String style = m.group();
                m.find();
                String color = m.group();
                m.find();
                int width = Integer.parseInt(m.group());
                Mode mode = Mode.SEPARATE;
                if (m.find()) {
                    String ms = m.group();
                    if (Mode.COLLAPSE_INNER.value.equalsIgnoreCase(ms)) {
                        mode = Mode.COLLAPSE_INNER;
                    } else if (Mode.COLLAPSE_OUTER.value.equalsIgnoreCase(ms)) {
                        mode = Mode.COLLAPSE_OUTER;
                    }
                }
                Color c;
                try {
                    c = ColorUtil.parseColorString(foUserAgent, color);
                } catch (PropertyException e) {
                    throw new IllegalArgumentException(e.getMessage());
                }
                int startRadius = 0;
                int endRadius = 0;
                if (m.find()) {
                    startRadius = Integer.parseInt(m.group());
                    m.find();
                    endRadius = Integer.parseInt(m.group());
                }
                return new BorderProps(style, width, startRadius, endRadius, c, mode);
            } else {
                throw new IllegalArgumentException("BorderProps must be surrounded by parentheses");
            }
        }
    }

}
