/* ====================================================================
   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.xdgf.usermodel.section;

import java.awt.geom.Path2D;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;

import com.microsoft.schemas.office.visio.x2012.main.RowType;
import com.microsoft.schemas.office.visio.x2012.main.SectionType;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.xdgf.geom.SplineCollector;
import org.apache.poi.xdgf.usermodel.XDGFCell;
import org.apache.poi.xdgf.usermodel.XDGFShape;
import org.apache.poi.xdgf.usermodel.XDGFSheet;
import org.apache.poi.xdgf.usermodel.section.geometry.Ellipse;
import org.apache.poi.xdgf.usermodel.section.geometry.GeometryRow;
import org.apache.poi.xdgf.usermodel.section.geometry.InfiniteLine;
import org.apache.poi.xdgf.usermodel.section.geometry.SplineKnot;
import org.apache.poi.xdgf.usermodel.section.geometry.SplineStart;

public class GeometrySection extends XDGFSection {

    GeometrySection _master;

    // rows
    SortedMap<Long, GeometryRow> _rows = new TreeMap<>();

    public GeometrySection(SectionType section, XDGFSheet containingSheet) {
        super(section, containingSheet);

        for (RowType row: section.getRowArray()) {
            if (_rows.containsKey(row.getIX()))
                throw new POIXMLException("Index element '" + row.getIX() + "' already exists");

            _rows.put(row.getIX(), GeometryRowTypes.load(row));
        }
    }

    @Override
    public void setupMaster(XDGFSection master) {

        _master = (GeometrySection)master;

        for (Entry<Long, GeometryRow> entry : _rows.entrySet()) {
            GeometryRow masterRow = _master._rows.get(entry.getKey());
            if (masterRow != null) {
                try {
                    entry.getValue().setupMaster(masterRow);
                } catch (ClassCastException e) {
                    // this can happen when a dynamic connector overrides its master's geometry
                    // .. probably can happen elsewhere too, I imagine.
                    //throw XDGFException.error("Mismatched geometry section '" + entry.getKey() + "' in master", this, e);
                }
            }
        }
    }

    // returns True if this row shouldn't be displayed
    public Boolean getNoShow() {
        Boolean noShow = XDGFCell.maybeGetBoolean(_cells, "NoShow");
        if (noShow == null) {
            if (_master != null)
                return _master.getNoShow();

            return false;
        }

        return noShow;
    }

    public Iterable<GeometryRow> getCombinedRows() {
        return new CombinedIterable<>(_rows,
                _master == null ? null : _master._rows);
    }

    public Path2D.Double getPath(XDGFShape parent) {

        Iterator<GeometryRow> rows = getCombinedRows().iterator();

        // special cases
        GeometryRow first = rows.hasNext() ? rows.next() : null;

        if (first instanceof Ellipse) {
            return ((Ellipse)first).getPath();
        } else if (first instanceof InfiniteLine) {
            return ((InfiniteLine)first).getPath();
        } else if (first instanceof SplineStart) {
            throw new POIXMLException("SplineStart must be preceded by another type");
        } else {

            // everything else is a path
            Path2D.Double path = new Path2D.Double();

            // dealing with splines makes this more complex
            SplineCollector renderer = null;
            GeometryRow row;

            while (true) {

                if (first != null) {
                    row = first;
                    first = null;
                } else {
                    if (!rows.hasNext())
                        break;
                    row = rows.next();
                }

                if (row instanceof SplineStart) {
                    if (renderer != null)
                        throw new POIXMLException("SplineStart found multiple times!");
                    renderer = new SplineCollector((SplineStart) row);
                } else if (row instanceof SplineKnot) {
                    if (renderer == null)
                        throw new POIXMLException("SplineKnot found without SplineStart!");
                    renderer.addKnot((SplineKnot) row);
                } else {
                    if (renderer != null) {
                        renderer.addToPath(path, parent);
                        renderer = null;
                    }

                    row.addToPath(path, parent);
                }
            }

            // just in case we end iteration
            if (renderer != null)
                renderer.addToPath(path, parent);

            return path;
        }
    }

}
