package usda.weru.mcrew.timeline;

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;

import usda.weru.mcrew.JulianCalendar;

/**
 * This class takes care of the rendering of items for the timeline.
 * @author jonathanhornbaker
 */
public class TimelineInterval
{
    private JulianCalendar start;
    private JulianCalendar end;
    private IntervalType type;
    private int spanX, spanY, origX, origY;
    private List<OperationIcon> icons;
    private final TimelinePanelData.ManageRow data;
    private boolean wrap;
    
    /**
     * Interval type determines the colors of the two rectangular areas we render.
     */
    public static enum IntervalType
    {
        GROWTH(Color.GREEN),
        FALLOW(Color.decode("#614126"));
        
        private final Color ground;
        
        IntervalType(Color input)
        {
            ground = input;
        }
    }
    
    /**
     * Basic constructor for an interval.  It must know it's start date, end date,
     * the type (growth or fallow) and have a link back to the managedata that
     * defines it.
     * @param begin
     * @param term
     * @param typ
     * @param panelData 
     */
    public TimelineInterval(JulianCalendar begin, JulianCalendar term, IntervalType typ, 
            TimelinePanelData.ManageRow panelData)
    {
        start = begin;
        end = term;
        wrap = begin.after(term);
        type = typ;
        data = panelData;
        icons = new ArrayList<OperationIcon>();
    }
    
    /**
     * Returns the start date of the interval.
     * @return 
     */
    public JulianCalendar getStart() { return start; }
    
    /**
     * Returns the end date of the interval.
     * @return 
     */
    public JulianCalendar getEnd() { return end; }
    
    /**
     * Returns true if the day is contained within the interval (inclusive start)
     * @param date
     * @return 
     */
    public boolean contains(JulianCalendar date)
    {
        if(wrap) return ((date.equals(start)) || (date.after(start)) || (end.after(date)));
        else return (((date.after(start)) && (end.after(date))) || date.equals(start));
    }
    
    /**
     * Returns the Icons contained within the interval.
     * @return 
     */
    public List<OperationIcon> getIcons() { return icons; }
    
    /**
     * Returns the y pixel location of the top of the interval.
     * @return 
     */
    public int getYOrigin() { return origY; }
    /**
     * Returns the y pixel location of the bottom of the interval.
     * @return 
     */
    public int getYEdge() { return spanY; }

    
    /**
     * Sets the lower corner of the interval.
     * @param x
     * @param y 
     */
    public void setLowerCorner(int x, int y)
    {
        spanX = x;
        spanY = y;
    }
    
    /**
     * Sets the upper corner of the interval.
     * @param x
     * @param y 
     */
    public void setUpperCorner(int x, int y)
    {
        origX = x;
        origY = y;
    }
    
    /**
     * Sets the total location of the interval.
     * @param upx
     * @param upy
     * @param lowx
     * @param lowy 
     */
    public void setLocation(int upx, int upy, int lowx, int lowy)
    {
        origX = upx;
        origY = upy;
        spanX = lowx;
        spanY = lowy;
    }
    
    /**
     * Places a new icon onto the list of icons.  It MUST already contain location information.
     * @param ic 
     */
    public void pushIcon(OperationIcon ic)
    {
        icons.add(ic);
    }
    
    /**
     * Removes the specified icon from the list of icons.  You MUST pass in the exact
     * icon to remove it.  The list of icons should be synched between this class and the
     * ManageRow class in TimelinePanelData.java.
     * @param ic 
     */
    public void popIcon(OperationIcon ic)
    {
        icons.remove(ic);
    }
    
    /**
     * Renders each Icon where it should be.  Ignores if the entire icon doesn't
     * fit into the itnerval.
     * @param grph
     * @param pixelStart
     * @param pixelEnd 
     */
    public void renderIcons(Graphics grph, JulianCalendar viewStart, JulianCalendar viewEnd)
    {
        for(OperationIcon ico : icons)
        {
            int origin = ico.getXOrigin();
            JulianCalendar day = ico.getRow().getDate();
            while(viewStart.after(day) && !day.after(viewEnd))
            {
                day = day.cloneDate().incrementYear(data.getRepeat());
                origin += data.getPixelRepeat();
            }
            ico.setBounds(origin, ico.getYOrigin(), TimelineConfig.height, TimelineConfig.height);
//            ico.setVisible(origin < pixelEnd);
            ico.repaint();
        }
    }
    
    /**
     * Returns the background color necessary for this interval.
     * @return 
     */
    public Color getBackground() { return type.ground; }   
    
    /**
     * Removes all operationicons attached to this interval.
     */
    public void clear() { icons = new ArrayList<OperationIcon>(); }
}
