/*
 * 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 {

    /** Separate border model */
    public static final int SEPARATE = 0;
    /** Collapsing border model, for borders inside a table */
    public static final int COLLAPSE_INNER = 1;
    /** Collapsing border model, for borders at the table's outer border */
    public static final int COLLAPSE_OUTER = 2;

    /** Border style (one of EN_*) */
    public int style; // Enum for border style
    /** Border color */
    public Color color;
    /** Border width */
    public int width;
    /** Border mode (one of SEPARATE, COLLAPSE_INNER and COLLAPSE_OUTER) */
    public int mode;

    /**
     * Constructs a new BorderProps instance.
     * @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 BorderProps(int style, int width, Color color, int mode) {
        this.style = style;
        this.width = width;
        this.color = color;
        this.mode = mode;
    }

    /**
     * Constructs a new BorderProps instance.
     * @param style border style (one of the XSL enum values for border style)
     * @param width border width
     * @param color border color
     * @param mode border mode ((one of SEPARATE, COLLAPSE_INNER and COLLAPSE_OUTER)
     */
    public BorderProps(String style, int width, Color color, int mode) {
        this(getConstantForStyle(style), width, color, 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) {
        if ((bp != null) && (bp.mode != SEPARATE)) {
            return bp.width / 2;
        } else {
            return 0;
        }
    }

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

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

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

    /** {@inheritDoc} */
    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)
                        && color.equals(other.color)
                        && width == other.width
                        && mode == other.mode;
            }
        }
        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) {
        if (s.startsWith("(") && s.endsWith(")")) {
            s = s.substring(1, s.length() - 1);
            Pattern pattern = Pattern.compile("([^,\\(]+(?:\\(.*\\))?)");
            Matcher m = pattern.matcher(s);
            boolean found;
            found = m.find();
            String style = m.group();
            found = m.find();
            String color = m.group();
            found = m.find();
            int width = Integer.parseInt(m.group());
            int mode = SEPARATE;
            found = m.find();
            if (found) {
                String ms = m.group();
                if ("collapse-inner".equalsIgnoreCase(ms)) {
                    mode = COLLAPSE_INNER;
                } else if ("collapse-outer".equalsIgnoreCase(ms)) {
                    mode = COLLAPSE_OUTER;
                }
            }
            Color c;
            try {
                c = ColorUtil.parseColorString(foUserAgent, color);
            } catch (PropertyException e) {
                throw new IllegalArgumentException(e.getMessage());
            }

            return new BorderProps(style, width, c, mode);
        } else {
            throw new IllegalArgumentException("BorderProps must be surrounded by parentheses");
        }
    }

    /** {@inheritDoc} */
    public String toString() {
        StringBuffer sbuf = new StringBuffer();
        sbuf.append('(');
        sbuf.append(getStyleString());
        sbuf.append(',');
        sbuf.append(ColorUtil.colorToString(color));
        sbuf.append(',');
        sbuf.append(width);
        if (mode != SEPARATE) {
            sbuf.append(',');
            if (mode == COLLAPSE_INNER) {
                sbuf.append("collapse-inner");
            } else {
                sbuf.append("collapse-outer");
            }
        }
        sbuf.append(')');
        return sbuf.toString();
    }

}
