/* ====================================================================
   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.
==================================================================== */

package org.apache.poi.hssf.usermodel;


/**
 * Common class for {@link HSSFHeader} and {@link HSSFFooter}.
 */
public abstract class HeaderFooter implements org.apache.poi.ss.usermodel.HeaderFooter {

    protected HeaderFooter() {
        //
    }
    
    /**
     * @return the internal text representation (combining center, left and right parts).
     * Possibly empty string if no header or footer is set.  Never <code>null</code>.
     */
    protected abstract String getRawText(); 
    
    private String[] splitParts() {
        String text = getRawText();
        // default values
        String _left = "";
        String _center = "";
        String _right = "";

        while (text.length() > 1) {
            if (text.charAt(0) != '&') {
                // Mimics the behaviour of Excel, which would put it in the center.
                _center = text;
                break;
            }
            int pos = text.length();
            switch (text.charAt(1)) {
            case 'L':
                if (text.contains("&C")) {
                    pos = Math.min(pos, text.indexOf("&C"));
                }
                if (text.contains("&R")) {
                    pos = Math.min(pos, text.indexOf("&R"));
                }
                _left = text.substring(2, pos);
                text = text.substring(pos);
                return new String[] { _left, _center, _right, };
            case 'C':
                if (text.contains("&L")) {
                    pos = Math.min(pos, text.indexOf("&L"));
                }
                if (text.contains("&R")) {
                    pos = Math.min(pos, text.indexOf("&R"));
                }
                _center = text.substring(2, pos);
                text = text.substring(pos);
                return new String[] { _left, _center, _right, };
            case 'R':
                if (text.contains("&C")) {
                    pos = Math.min(pos, text.indexOf("&C"));
                }
                if (text.contains("&L")) {
                    pos = Math.min(pos, text.indexOf("&L"));
                }
                _right = text.substring(2, pos);
                text = text.substring(pos);
                return new String[] { _left, _center, _right, };
            default:
                // Mimics the behaviour of Excel, which would put it in the center.
                _center = text;
                break;
            }
        }
        return null;
    }

    /**
     * @return the left side of the header or footer.
     */
    public final String getLeft() {
        return splitParts()[0];
    }

    /**
     * @param newLeft The string to set as the left side.
     */
    public final void setLeft(String newLeft) {
        updatePart(0, newLeft); 
    }

    /**
     * @return the center of the header or footer.
     */
    public final String getCenter() {
        return splitParts()[1];
    }

    /**
     * @param newCenter The string to set as the center.
     */
    public final void setCenter(String newCenter) {
        updatePart(1, newCenter); 
    }

    /**
     * @return The right side of the header or footer.
     */
    public final String getRight() {
        return splitParts()[2];
    }

    /**
     * @param newRight The string to set as the right side.
     */
    public final void setRight(String newRight) {
        updatePart(2, newRight); 
    }
    
    private void updatePart(int partIndex, String newValue) {
        String[] parts = splitParts();
        parts[partIndex] = newValue == null ? "" : newValue;
        updateHeaderFooterText(parts);
    }
    /**
     * Creates the complete footer string based on the left, center, and middle
     * strings.
     */
    private void updateHeaderFooterText(String[] parts) {
        String _left = parts[0];
        String _center = parts[1];
        String _right = parts[2];
        
        if (_center.length() < 1 && _left.length() < 1 && _right.length() < 1) {
            setHeaderFooterText("");
            return;
        }
        StringBuilder sb = new StringBuilder(64);
        sb.append("&C");
        sb.append(_center);
        sb.append("&L");
        sb.append(_left);
        sb.append("&R");
        sb.append(_right);
        String text = sb.toString();
        setHeaderFooterText(text);
    }

    /**
     * @param text the new header footer text (contains mark-up tags). Possibly
     *            empty string never <code>null</code>
     */
    protected abstract void setHeaderFooterText(String text);

    /**
     * @param size
     *            the new font size
     * @return The mark-up tag representing a new font size
     */
    public static String fontSize(short size) {
        return "&" + size;
    }

    /**
     * @param font
     *            the new font
     * @param style
     *            the fonts style, one of regular, italic, bold, italic bold or
     *            bold italic
     * @return The mark-up tag representing a new font size
     */
    public static String font(String font, String style) {
        return "&\"" + font + "," + style + "\"";
    }

    /**
     * @return The mark-up tag representing the current page number
     */
    public static String page() {
        return MarkupTag.PAGE_FIELD.getRepresentation();
    }

    /**
     * @return The mark-up tag representing the number of pages
     */
    public static String numPages() {
        return MarkupTag.NUM_PAGES_FIELD.getRepresentation();
    }

    /**
     * @return The mark-up tag representing the current date date
     */
    public static String date() {
        return MarkupTag.DATE_FIELD.getRepresentation();
    }

    /**
     * @return The mark-up tag representing current time
     */
    public static String time() {
        return MarkupTag.TIME_FIELD.getRepresentation();
    }

    /**
     * @return The mark-up tag representing the current file name
     */
    public static String file() {
        return MarkupTag.FILE_FIELD.getRepresentation();
    }

    /**
     * @return The mark-up tag representing the current tab (sheet) name
     */
    public static String tab() {
        return MarkupTag.SHEET_NAME_FIELD.getRepresentation();
    }

    /**
     * @return The mark-up tag for start bold
     */
    public static String startBold() {
        return MarkupTag.BOLD_FIELD.getRepresentation();
    }

    /**
     * @return The mark-up tag for end bold
     */
    public static String endBold() {
        return MarkupTag.BOLD_FIELD.getRepresentation();
    }

    /**
     * @return The mark-up tag for start underline
     */
    public static String startUnderline() {
        return MarkupTag.UNDERLINE_FIELD.getRepresentation();
    }

    /**
     * @return The mark-up tag for end underline
     */
    public static String endUnderline() {
        return MarkupTag.UNDERLINE_FIELD.getRepresentation();
    }

    /**
     * @return The mark-up tag for start double underline
     */
    public static String startDoubleUnderline() {
        return MarkupTag.DOUBLE_UNDERLINE_FIELD.getRepresentation();
    }

    /**
     * @return The mark-up tag for end double underline
     */
    public static String endDoubleUnderline() {
        return MarkupTag.DOUBLE_UNDERLINE_FIELD.getRepresentation();
    }

    /**
     * Removes any fields (eg macros, page markers etc) from the string.
     * Normally used to make some text suitable for showing to humans, and the
     * resultant text should not normally be saved back into the document!
     */
    public static String stripFields(String pText) {
        int pos;

        // Check we really got something to work on
        if (pText == null || pText.length() == 0) {
            return pText;
        }

        String text = pText;

        // Firstly, do the easy ones which are static
        for (MarkupTag mt : MarkupTag.values()) {
            String seq = mt.getRepresentation();
            while ((pos = text.indexOf(seq)) >= 0) {
                text = text.substring(0, pos) + text.substring(pos + seq.length());
            }
        }

        // Now do the tricky, dynamic ones
        // These are things like font sizes and font names
        text = text.replaceAll("\\&\\d+", "");
        text = text.replaceAll("\\&\".*?,.*?\"", "");

        // All done
        return text;
    }

    private enum MarkupTag {
        SHEET_NAME_FIELD ("&A", false),
        DATE_FIELD       ("&D", false),
        FILE_FIELD       ("&F", false),
        FULL_FILE_FIELD  ("&Z", false),
        PAGE_FIELD       ("&P", false),
        TIME_FIELD       ("&T", false),
        NUM_PAGES_FIELD  ("&N", false),

        PICTURE_FIELD    ("&G", false),

        BOLD_FIELD             ("&B", true),
        ITALIC_FIELD           ("&I", true),
        STRIKETHROUGH_FIELD    ("&S", true),
        SUBSCRIPT_FIELD        ("&Y", true),
        SUPERSCRIPT_FIELD      ("&X", true),
        UNDERLINE_FIELD        ("&U", true),
        DOUBLE_UNDERLINE_FIELD ("&E", true),
        ;
        
        private final String _representation;
        private final boolean _occursInPairs;
        private MarkupTag(String sequence, boolean occursInPairs) {
            _representation = sequence;
            _occursInPairs = occursInPairs;
        }
        /**
         * @return The character sequence that marks this field
         */
        public String getRepresentation() {
            return _representation;
        }

        /**
         * @return true if this markup tag normally comes in a pair, eg turn on
         *         underline / turn off underline
         */
        public boolean occursPairs() {
            return _occursInPairs;
        }
    }
}
