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

import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.apache.batik.dom.svg.SVGDOMImplementation;

import org.apache.fop.svg.SVGUtilities;

/**
 * Simple plan drawer implementation.
 */
public class SimplePlanDrawer implements PlanDrawer {

    private static final String SVG_NAMESPACE = SVGDOMImplementation.SVG_NAMESPACE_URI;

    private float fontSize;
    private HashMap hints;
    private java.awt.Font font = null;
    private boolean bord = false;
    private float lSpace = 15;
    private float width;
    private float height;
    private float topEdge;
    private float rightEdge;

    private String[] colours;
    private String[] darkcolours;

    private Date startDate;
    private Date endDate;

    /**
     * Sets the start date.
     * @param sd start date
     */
    public void setStartDate(Date sd) {
        startDate = sd;
    }

    /**
     * Sets the end date.
     * @param ed end date
     */
    public void setEndDate(Date ed) {
        endDate = ed;
    }

    /**
     * @see org.apache.fop.plan.PlanDrawer#createDocument(EventList, float, float, HashMap)
     */
    public Document createDocument(EventList data, float w, float h,
                                   HashMap hints) {
        this.width = w;
        this.height = h;
        this.hints = hints;
        fontSize = ((Float) hints.get(PlanHints.FONT_SIZE)).floatValue();
        bord = ((Boolean) hints.get(PlanHints.PLAN_BORDER)).booleanValue();

        String title = "";

        DOMImplementation impl
            = SVGDOMImplementation.getDOMImplementation();
        Document doc = impl.createDocument(SVG_NAMESPACE, "svg", null);

        Element svgRoot = doc.getDocumentElement();
        svgRoot.setAttributeNS(null, "width", Float.toString(width));
        svgRoot.setAttributeNS(null, "height", Float.toString(height));
        svgRoot.setAttributeNS(null, "viewBox",
                "0 0 " + Float.toString(width) + " " + Float.toString(height));
        svgRoot.setAttributeNS(null, "style",
                               "font-size:" + 8
                                   + ";font-family:"
                                   + hints.get(PlanHints.FONT_FAMILY));

        font = new java.awt.Font((String)hints.get(PlanHints.FONT_FAMILY),
                                  java.awt.Font.PLAIN, (int)fontSize);

        if (bord) {
            Element border
                = SVGUtilities.createRect(doc, 0, 0, width, height);
            border.setAttributeNS(null, "style", "stroke:black;fill:none");
            svgRoot.appendChild(border);
        }

        float strwidth = SVGUtilities.getStringWidth(title, font);

        Element text;
        float pos = (float)(80 - strwidth / 2.0);
        if (pos < 5) {
            pos = 5;
        }
        text = SVGUtilities.createText(doc, pos, 18, title);
        text.setAttributeNS(null, "style", "font-size:14");
        svgRoot.appendChild(text);

        topEdge = SVGUtilities.getStringHeight(title, font) + 5;

        // add the actual pie chart
        addPlan(doc, svgRoot, data);
        //addLegend(doc, svgRoot, data);

        return doc;
    }

    protected void addPlan(Document doc, Element svgRoot, EventList data) {
        Date currentDate = new Date();

        Date lastWeek = startDate;
        Date future = endDate;
        Calendar lw = Calendar.getInstance();
        if (lastWeek == null || future == null) {
            int dow = lw.get(Calendar.DAY_OF_WEEK);
            lw.add(Calendar.DATE, -dow - 6);
            lastWeek = lw.getTime();
            lw.add(Calendar.DATE, 5 * 7);
            future = lw.getTime();
        }
        long totalDays = (long)((future.getTime() - lastWeek.getTime() + 43200000) / 86400000);
        lw.setTime(lastWeek);
        int startDay = lw.get(Calendar.DAY_OF_WEEK);

        float graphTop = topEdge;
        Element g;
        Element line;
        line = SVGUtilities.createLine(doc, 0, topEdge, width, topEdge);
        line.setAttributeNS(null, "style", "fill:none;stroke:black");
        svgRoot.appendChild(line);

        Element clip1 = SVGUtilities.createClip(doc,
                SVGUtilities.createPath(doc,
                    "m0 0l126 0l0 " + height + "l-126 0z"), "clip1");
        Element clip2 = SVGUtilities.createClip(doc,
                SVGUtilities.createPath(doc,
                    "m130 0l66 0l0 " + height + "l-66 0z"), "clip2");
        Element clip3 = SVGUtilities.createClip(doc,
                SVGUtilities.createPath(doc,
                    "m200 0l" + (width - 200) + " 0l0 " + height + "l-"
                        + (width - 200) + " 0z"), "clip3");
        svgRoot.appendChild(clip1);
        svgRoot.appendChild(clip2);
        svgRoot.appendChild(clip3);

        DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
        Element text;
        text = SVGUtilities.createText(doc, 201, topEdge - 1,
                                       df.format(lastWeek));
        svgRoot.appendChild(text);

        text = SVGUtilities.createText(doc, width, topEdge - 1,
                                       df.format(future));
        text.setAttributeNS(null, "text-anchor", "end");
        svgRoot.appendChild(text);

        line = SVGUtilities.createLine(doc, 128, topEdge, 128, height);
        line.setAttributeNS(null, "style", "fill:none;stroke:rgb(150,150,150)");
        svgRoot.appendChild(line);
        int offset = 0;
        for (int count = startDay; count < startDay + totalDays - 1; count++) {
            offset++;
            if (count % 7 == 0 || count % 7 == 1) {
                Element rect = SVGUtilities.createRect(doc,
                    200 + (offset - 1) * (width - 200) / (totalDays - 2),
                    (float)(topEdge + 0.5),
                    (width - 200) / (totalDays - 3),
                    height - 1 - topEdge);
                rect.setAttributeNS(null, "style", "stroke:none;fill:rgb(230,230,230)");
                svgRoot.appendChild(rect);
            }
            line = SVGUtilities.createLine(doc,
                                           200 + (offset - 1) * (width - 200) / (totalDays - 2),
                                           (float)(topEdge + 0.5),
                                           200 + (offset - 1) * (width - 200) / (totalDays - 2),
                                           (float)(height - 0.5));
            line.setAttributeNS(null, "style", "fill:none;stroke:rgb(200,200,200)");
            svgRoot.appendChild(line);
        }


        for (int count = 0; count < data.getSize(); count++) {
            GroupInfo gi = data.getGroupInfo(count);
            g = SVGUtilities.createG(doc);
            text = SVGUtilities.createText(doc, 1, topEdge + 12,
                                           gi.getName());
            text.setAttributeNS(null, "style", "clip-path:url(#clip1)");
            g.appendChild(text);
            if (count > 0) {
                line = SVGUtilities.createLine(doc, 0, topEdge + 2,
                                               width, topEdge + 2);
                line.setAttributeNS(null, "style", "fill:none;stroke:rgb(100,100,100)");
                g.appendChild(line);
            }

            float lastTop = topEdge;
            topEdge += 14;
            boolean showing = false;
            for (int count1 = 0; count1 < gi.getSize(); count1++) {
                ActionInfo act = gi.getActionInfo(count1);
                String name = act.getOwner();
                String label = act.getLabel();
                text = SVGUtilities.createText(doc, 8, topEdge + 12, label);
                text.setAttributeNS(null, "style", "clip-path:url(#clip1)");
                g.appendChild(text);

                text = SVGUtilities.createText(doc, 130, topEdge + 12,
                                               name);
                text.setAttributeNS(null, "style", "clip-path:url(#clip2)");
                g.appendChild(text);
                int type = act.getType();
                Date start = act.getStartDate();
                Date end = act.getEndDate();
                if (end.after(lastWeek) && start.before(future)) {
                    showing = true;
                    int left = 200;
                    int right = 500;

                    int daysToStart = (int)((start.getTime()
                                - lastWeek.getTime() + 43200000) / 86400000);
                    int days = (int)((end.getTime() - start.getTime()
                                + 43200000) / 86400000);
                    int daysFromEnd
                        = (int)((future.getTime() - end.getTime()
                            + 43200000) / 86400000);
                    Element taskGraphic;
                    switch (type) {
                        case ActionInfo.TASK:
                            taskGraphic = SVGUtilities.createRect(doc,
                                left + daysToStart * 300 / (totalDays - 2),
                                topEdge + 2, days * 300 / (totalDays - 2), 10);
                            taskGraphic.setAttributeNS(null,
                                "style",
                                "stroke:black;fill:blue;stroke-width:1;clip-path:url(#clip3)");
                            g.appendChild(taskGraphic);
                            break;
                        case ActionInfo.MILESTONE:
                            taskGraphic = SVGUtilities.createPath(doc,
                                "m " + (left
                                    + daysToStart * 300 / (totalDays - 2) - 6)
                                    + " " + (topEdge + 6) + "l6 6l6-6l-6-6z");
                            taskGraphic.setAttributeNS(null,
                                "style",
                                "stroke:black;fill:black;stroke-width:1;clip-path:url(#clip3)");
                            g.appendChild(taskGraphic);
                            text = SVGUtilities.createText(doc,
                                left + daysToStart * 300 / (totalDays - 2) + 8,
                                topEdge + 9, df.format(start));
                            g.appendChild(text);

                            break;
                        case ActionInfo.GROUPING:
                            taskGraphic = SVGUtilities.createPath(doc,
                                "m " + (left
                                    + daysToStart * 300 / (totalDays - 2) - 6)
                                    + " " + (topEdge + 6) + "l6 -6l"
                                    + (days * 300 / (totalDays - 2))
                                    + " 0l6 6l-6 6l-4-4l"
                                    + -(days * 300 / (totalDays - 2) - 8)
                                    + " 0l-4 4l-6-6z");
                            taskGraphic.setAttributeNS(null,
                                "style",
                                "stroke:black;fill:black;stroke-width:1;clip-path:url(#clip3)");
                            g.appendChild(taskGraphic);
                            break;
                        default:
                            break;
                    }
                }

                topEdge += 14;
            }
            if (showing) {
                svgRoot.appendChild(g);
            } else {
                topEdge = lastTop;
            }
        }
        int currentDays
            = (int)((currentDate.getTime() - lastWeek.getTime()
                + 43200000) / 86400000);

        text = SVGUtilities.createText(doc,
                                       (float)(200 + (currentDays + 0.5) * 300 / 35),
                                       graphTop - 1, df.format(currentDate));
        text.setAttributeNS(null, "text-anchor", "middle");
        text.setAttributeNS(null, "style", "stroke:rgb(100,100,100)");
        svgRoot.appendChild(text);

        line = SVGUtilities.createLine(doc,
                                       (float)(200 + (currentDays + 0.5) * 300 / 35), graphTop,
                                       (float)(200 + (currentDays + 0.5) * 300 / 35), height);
        line.setAttributeNS(null, "style", "fill:none;stroke:rgb(200,50,50);stroke-dasharray:5,5");
        svgRoot.appendChild(line);


    }
}
