/*
 *  ====================================================================
 *    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.sl.draw.geom;

import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;

import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.sl.usermodel.PaintStyle.PaintModifier;
import org.apache.poi.util.Internal;

@Internal
class PresetParser {
    enum Mode {
        FILE(PresetParser::updateFile),
        SHAPE_LST(PresetParser::updateShapeList),
        SHAPE(PresetParser::updateShape),
        GUIDE_LST(PresetParser::updateGuideList),
        AH_LST(PresetParser::updateAhList),
        CXN_LST(PresetParser::updateCxnList),
        PATH_LST(PresetParser::updatePathLst),
        PATH(PresetParser::updatePath);

        interface Handler {
            void update(PresetParser parser, XMLStreamReader sr) throws XMLStreamException;
        }

        final Handler handler;

        Mode(Handler handler) {
            this.handler = handler;
        }
    }

    private static final Logger LOG = LogManager.getLogger(PresetParser.class);

    private Mode mode;

    private final Map<String, CustomGeometry> geom = new HashMap<>();
    private CustomGeometry customGeometry;
    private boolean useAdjustValue;
    private Path path;


    PresetParser(Mode mode) {
        this.mode = mode;
        if (mode == Mode.SHAPE) {
            customGeometry = new CustomGeometry();
            geom.put("custom", customGeometry);
        }
    }

    void parse(XMLStreamReader sr) throws XMLStreamException {
        while (sr.hasNext()) {
            switch (sr.next()) {
                case XMLStreamConstants.START_ELEMENT:
                    mode.handler.update(this, sr);
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    endContext();
                    break;
                case XMLStreamConstants.END_DOCUMENT:
                    return;
                default:
                    break;
            }
        }
    }

    Map<String, CustomGeometry> getGeom() {
        return geom;
    }

    private void updateFile(XMLStreamReader sr) {
        final String name = sr.getLocalName();
        assert("presetShapeDefinitons".equals(name));
        mode = Mode.SHAPE_LST;
    }

    private void updateShapeList(XMLStreamReader sr) {
        final String name = sr.getLocalName();
        customGeometry = new CustomGeometry();
        if (geom.containsKey(name)) {
            LOG.atWarn().log("Duplicate definition of {}", name);
        }
        geom.put(name, customGeometry);
        mode = Mode.SHAPE;
    }

    private void updateShape(XMLStreamReader sr) throws XMLStreamException {
        final String name = sr.getLocalName();
        switch (name) {
            case "avLst":
                useAdjustValue = true;
                mode = Mode.GUIDE_LST;
                break;
            case "gdLst":
                useAdjustValue = false;
                mode = Mode.GUIDE_LST;
                break;
            case "ahLst":
                mode = Mode.AH_LST;
                break;
            case "cxnLst":
                mode = Mode.CXN_LST;
                break;
            case "rect":
                addRectangle(sr);
                break;
            case "pathLst":
                mode = Mode.PATH_LST;
                break;
        }
    }

    private void updateGuideList(XMLStreamReader sr) throws XMLStreamException {
        final String name = sr.getLocalName();
        assert("gd".equals(name));
        final Guide gd;
        if (useAdjustValue) {
            customGeometry.addAdjustGuide((AdjustValue)(gd = new AdjustValue()));
        } else {
            customGeometry.addGeomGuide(gd = new Guide());
        }

        parseAttributes(sr, (key,val) -> {
            switch (key) {
                case "name":
                    // CollapsedStringAdapter
                    gd.setName(collapseString(val));
                    break;
                case "fmla":
                    gd.setFmla(val);
                    break;
            }
        });

        int tag = nextTag(sr);
        assert(tag == XMLStreamConstants.END_ELEMENT);
    }


    private void updateAhList(XMLStreamReader sr) throws XMLStreamException {
        String name = sr.getLocalName();
        switch (name) {
            case "ahXY":
                addXY(sr);
                break;

            case "ahPolar":
                addPolar(sr);
                break;
        }
    }

    private void addXY(XMLStreamReader sr) throws XMLStreamException {
        XYAdjustHandle ahXY = new XYAdjustHandle();
        customGeometry.addAdjustHandle(ahXY);

        parseAttributes(sr, (key, val) -> {
            switch (key) {
                case "gdRefX":
                    ahXY.setGdRefX(collapseString(val));
                    break;
                case "minX":
                    ahXY.setMinX(val);
                    break;
                case "maxX":
                    ahXY.setMaxX(val);
                    break;
                case "gdRefY":
                    ahXY.setGdRefY(collapseString(val));
                    break;
                case "minY":
                    ahXY.setMinY(val);
                    break;
                case "maxY":
                    ahXY.setMaxY(val);
                    break;
            }
        });

        ahXY.setPos(parsePosPoint(sr));
    }

    private void addPolar(XMLStreamReader sr) throws XMLStreamException {
        PolarAdjustHandle ahPolar = new PolarAdjustHandle();
        customGeometry.addAdjustHandle(ahPolar);

        parseAttributes(sr, (key, val) -> {
            switch (key) {
                case "gdRefR":
                    ahPolar.setGdRefR(collapseString(val));
                    break;
                case "minR":
                    ahPolar.setMinR(val);
                    break;
                case "maxR":
                    ahPolar.setMaxR(val);
                    break;
                case "gdRefAng":
                    ahPolar.setGdRefAng(collapseString(val));
                    break;
                case "minAng":
                    ahPolar.setMinAng(val);
                    break;
                case "maxAng":
                    ahPolar.setMaxAng(val);
                    break;
            }
        });

        ahPolar.setPos(parsePosPoint(sr));
    }

    private void updateCxnList(XMLStreamReader sr) throws XMLStreamException {
        String name = sr.getLocalName();
        assert("cxn".equals(name));

        ConnectionSite cxn = new ConnectionSite();
        customGeometry.addConnectionSite(cxn);

        parseAttributes(sr, (key, val) -> {
            if ("ang".equals(key)) {
                cxn.setAng(val);
            }
        });

        cxn.setPos(parsePosPoint(sr));
    }

    private void updatePathLst(XMLStreamReader sr) {
        String name = sr.getLocalName();
        assert("path".equals(name));

        path = new Path();
        customGeometry.addPath(path);

        parseAttributes(sr, (key, val) -> {
            switch (key) {
                case "w":
                    path.setW(Long.parseLong(val));
                    break;
                case "h":
                    path.setH(Long.parseLong(val));
                    break;
                case "fill":
                    path.setFill(mapFill(val));
                    break;
                case "stroke":
                    path.setStroke(Boolean.parseBoolean(val));
                    break;
                case "extrusionOk":
                    path.setExtrusionOk(Boolean.parseBoolean(val));
                    break;
            }
        });

        mode = Mode.PATH;
    }

    private static PaintModifier mapFill(String fill) {
        switch (fill) {
            default:
            case "none":
                return PaintModifier.NONE;
            case "norm":
                return PaintModifier.NORM;
            case "lighten":
                return PaintModifier.LIGHTEN;
            case "lightenLess":
                return PaintModifier.LIGHTEN_LESS;
            case "darken":
                return PaintModifier.DARKEN;
            case "darkenLess":
                return PaintModifier.DARKEN_LESS;
        }
    }

    private void updatePath(XMLStreamReader sr) throws XMLStreamException {
        String name = sr.getLocalName();
        switch (name) {
            case "close":
                closePath(sr);
                break;
            case "moveTo":
                moveTo(sr);
                break;
            case "lnTo":
                lineTo(sr);
                break;
            case "arcTo":
                arcTo(sr);
                break;
            case "quadBezTo":
                quadBezTo(sr);
                break;
            case "cubicBezTo":
                cubicBezTo(sr);
                break;
        }
    }

    private void closePath(XMLStreamReader sr) throws XMLStreamException {
        path.addCommand(new ClosePathCommand());
        int tag = nextTag(sr);
        assert(tag == XMLStreamConstants.END_ELEMENT);
    }

    private void moveTo(XMLStreamReader sr) throws XMLStreamException {
        MoveToCommand cmd = new MoveToCommand();
        path.addCommand(cmd);

        AdjustPoint pt = parsePtPoint(sr, true);
        assert(pt != null);
        cmd.setPt(pt);
    }

    private void lineTo(XMLStreamReader sr) throws XMLStreamException {
        LineToCommand cmd = new LineToCommand();
        path.addCommand(cmd);

        AdjustPoint pt = parsePtPoint(sr, true);
        assert(pt != null);
        cmd.setPt(pt);
    }

    private void arcTo(XMLStreamReader sr) throws XMLStreamException {
        ArcToCommand cmd = new ArcToCommand();
        path.addCommand(cmd);
        parseAttributes(sr, (key, val) -> {
            switch (key) {
                case "wR":
                    cmd.setWR(val);
                    break;
                case "hR":
                    cmd.setHR(val);
                    break;
                case "stAng":
                    cmd.setStAng(val);
                    break;
                case "swAng":
                    cmd.setSwAng(val);
                    break;
            }
        });
        int tag = nextTag(sr);
        assert (tag == XMLStreamConstants.END_ELEMENT);
    }

    private void quadBezTo(XMLStreamReader sr) throws XMLStreamException {
        QuadToCommand cmd = new QuadToCommand();
        path.addCommand(cmd);
        AdjustPoint pt1 = parsePtPoint(sr, false);
        AdjustPoint pt2 = parsePtPoint(sr, true);
        assert (pt1 != null && pt2 != null);
        cmd.setPt1(pt1);
        cmd.setPt2(pt2);
    }

    private void cubicBezTo(XMLStreamReader sr) throws XMLStreamException {
        CurveToCommand cmd = new CurveToCommand();
        path.addCommand(cmd);
        AdjustPoint pt1 = parsePtPoint(sr, false);
        AdjustPoint pt2 = parsePtPoint(sr, false);
        AdjustPoint pt3 = parsePtPoint(sr, true);
        assert (pt1 != null && pt2 != null && pt3 != null);
        cmd.setPt1(pt1);
        cmd.setPt2(pt2);
        cmd.setPt3(pt3);
    }

    private void addRectangle(XMLStreamReader sr) throws XMLStreamException {
        String[] ltrb = new String[4];
        parseAttributes(sr, (key,val) -> {
            switch (key) {
                case "l":
                    ltrb[0] = val;
                    break;
                case "t":
                    ltrb[1] = val;
                    break;
                case "r":
                    ltrb[2] = val;
                    break;
                case "b":
                    ltrb[3] = val;
                    break;
            }
        });

        customGeometry.setTextBounds(ltrb[0],ltrb[1],ltrb[2],ltrb[3]);

        int tag = nextTag(sr);
        assert(tag == XMLStreamConstants.END_ELEMENT);
    }


    private void endContext() {
        switch (mode) {
            case FILE:
            case SHAPE_LST:
                mode = Mode.FILE;
                break;
            case SHAPE:
                mode = Mode.SHAPE_LST;
                break;
            case CXN_LST:
            case AH_LST:
            case GUIDE_LST:
            case PATH_LST:
                useAdjustValue = false;
                path = null;
                mode = Mode.SHAPE;
                break;
            case PATH:
                path = null;
                mode = Mode.PATH_LST;
                break;
        }
    }

    private AdjustPoint parsePosPoint(XMLStreamReader sr) throws XMLStreamException {
        return parseAdjPoint(sr, true, "pos");
    }

    private AdjustPoint parsePtPoint(XMLStreamReader sr, boolean closeOuter) throws XMLStreamException {
        return parseAdjPoint(sr, closeOuter, "pt");
    }

    private AdjustPoint parseAdjPoint(XMLStreamReader sr, boolean closeOuter, String name) throws XMLStreamException {
        int tag = nextTag(sr);
        if (tag == XMLStreamConstants.END_ELEMENT) {
            return null;
        }

        assert (name.equals(sr.getLocalName()));

        AdjustPoint pos = new AdjustPoint();
        parseAttributes(sr, (key, val) -> {
            switch (key) {
                case "x":
                    pos.setX(val);
                    break;
                case "y":
                    pos.setY(val);
                    break;
            }
        });
        tag = nextTag(sr);
        assert(tag == XMLStreamConstants.END_ELEMENT);
        if (closeOuter) {
            tag = nextTag(sr);
            assert(tag == XMLStreamConstants.END_ELEMENT);
        }
        return pos;
    }

    private void parseAttributes(XMLStreamReader sr, BiConsumer<String,String> c) {
        for (int i=0; i<sr.getAttributeCount(); i++) {
            c.accept(sr.getAttributeLocalName(i), sr.getAttributeValue(i));
        }
    }

    /**
     * Reimplement {@link XMLStreamReader#nextTag()} because of differences of XmlBeans and Xerces XMLStreamReader.
     * XmlBeans doesn't return the END_ELEMENT on nextTag()
     *
     * @param sr the stream reader
     * @return the next tag type (START_ELEMENT, END_ELEMENT, END_DOCUMENT)
     * @throws XMLStreamException if reading the next tag fails
     */
    private static int nextTag(XMLStreamReader sr) throws XMLStreamException {
        int tag;
        do {
            tag = sr.next();
        } while (
            tag != XMLStreamConstants.START_ELEMENT &&
            tag != XMLStreamConstants.END_ELEMENT &&
            tag != XMLStreamConstants.END_DOCUMENT
        );
        return tag;
    }

    /**
     * Removes leading and trailing whitespaces of the string given as the parameter, then truncate any
     * sequence of tab, CR, LF, and SP by a single whitespace character ' '.
     */
    private static String collapseString(String text) {
        if (text==null) {
            return null;
        }

        int len = text.length();

        // most of the texts are already in the collapsed form. so look for the first whitespace in the hope that we
        // will never see it.
        int s;
        for (s=0; s<len; s++) {
            if (isWhiteSpace(text.charAt(s))) {
                break;
            }
        }

        if (s == len) {
            // the input happens to be already collapsed.
            return text;
        }

        // we now know that the input contains spaces. let's sit down and do the collapsing normally.
        // allocate enough size to avoid re-allocation
        StringBuilder result = new StringBuilder(len);

        if (s != 0) {
            for(int i=0; i<s; i++) {
                result.append(text.charAt(i));
            }
            result.append(' ');
        }

        boolean inStripMode = true;
        for (int i = s+1; i < len; i++) {
            char ch = text.charAt(i);
            boolean b = isWhiteSpace(ch);

            if (inStripMode && b) {
                // skip this character
                continue;
            }

            inStripMode = b;
            result.append(inStripMode ? ' ' : ch);
        }

        // remove trailing whitespaces
        len = result.length();
        if (len > 0 && result.charAt(len - 1) == ' ') {
            result.setLength(len - 1);
        }

        // whitespaces are already collapsed, so all we have to do is
        // to remove the last one character if it's a whitespace.
        return result.toString();
    }

    /** returns true if the specified char is a white space character. */
    private static boolean isWhiteSpace(char ch) {
        return ch == 0x9 || ch == 0xA || ch == 0xD || ch == 0x20;
    }
}
