/**
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * Copyright © 2009 Mindoo GmbH
 *
 * @author Tammo Riedinger
 *
 */
package com.mindoo.ec09.legacy;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;

import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JScrollPane;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.general.Dataset;
import org.jfree.data.general.PieDataset;
import org.jfree.data.xml.DatasetReader;

import com.mindoo.ec09.framework.views.ViewData;
import com.mindoo.ec09.legacy.PictureView.ImageComponent;

public class ChartView extends AbstractView {
	private static Map<String,String> ACTION_MAPPING=new LinkedHashMap<String,String>();
	static {
		ACTION_MAPPING.put("Zoom in",ImageComponent.ACTION_ZOOM_IN);
		ACTION_MAPPING.put("Zoom out",ImageComponent.ACTION_ZOOM_OUT);
	};
	
	private Component m_component;
	private ChartComponent m_chartComponent;
	
	public ChartView() {
	}
	
	public ChartView(String title, ViewData data) {
		initialize(title, data);
	}
	
	private Dataset readDataSet(final ViewData data) {
		InputStream in=null;
		try {
			in=new BufferedInputStream(data.openStream());

			Scanner s = new Scanner(in);
			s.useDelimiter("\n");
			
			while (s.findInLine("<[ ]*(CategoryDataset|PieDataset)[ ]*>")!=null) {
				InputStream dataSetIn=null;
				try{
					dataSetIn=new BufferedInputStream(data.openStream());
					
					String result=s.match().group(1);
					
					if ("CategoryDataset".equals(result)) {
						return DatasetReader.readCategoryDatasetFromXML(dataSetIn);
					}
					else if ("PieDataset".equals(result))
						return DatasetReader.readPieDatasetFromXML(dataSetIn);
				}
				catch (Exception e) {
					e.printStackTrace();
				}
				finally {
					try {
						dataSetIn.close();
					}
					catch(Exception ignore) {}
				}
			}
		}
		catch (Throwable e) {
			e.printStackTrace();
		}
		finally {
			try {
				in.close();
			}
			catch(Exception ignore) {}
		}
		
		return null; 
	}
	
	protected String formatTitle(String title) {
		if (title.length()>25)
			return "..." + title.substring(title.length()-22, title.length());
		
		return title;
	}
	
	@Override
	protected void dataChanged() {
		if (m_chartComponent!=null) {
			Dataset ds=readDataSet(getData());
			
			JFreeChart chart=null;
			if (ds!=null) {
				if (ds instanceof PieDataset) {
					// create the chart...
			        chart=ChartFactory.createPieChart(
			        	formatTitle(getTitle()),
			            (PieDataset)ds,
			            true,
			            true,
			            false
			        );
				}
				else if (ds instanceof CategoryDataset) {
					chart = ChartFactory.createBarChart(
							formatTitle(getTitle()),
				            "Domain", 
				            "Range",
				            (CategoryDataset)ds,
				            PlotOrientation.VERTICAL,
				            true,
				            true,
				            false
				        );
				}
			}

			m_chartComponent.setChart(chart);
		}
	}
	
	public Component createComponent() {
		m_chartComponent=new ChartComponent();
		
		dataChanged();
		
		m_component=new JScrollPane(m_chartComponent);
		
        return m_component;
	}

	public Action getAction(String name) {
		if (m_chartComponent!=null) {
			String mappedName=ACTION_MAPPING.get(name);
			
			if (mappedName!=null)
				return ((JComponent)m_chartComponent).getActionMap().get(mappedName);
		}
		return null;
	}

	public Iterator<String> getActionNames() {
		return ACTION_MAPPING.keySet().iterator();
	}
	
	public static class ChartComponent extends ScaledComponent {
		private static final long serialVersionUID = 7516895545722219045L;
		private JFreeChart m_chart;
		private Rectangle m_chartArea=new Rectangle(0,0,200,200);
		private Dimension m_baseSize=new Dimension(200,200);
		private boolean m_dirty;
		
		public ChartComponent() {
			super();
		}
		
		public void setChart(JFreeChart chart) {
			if (m_chart==chart)
				return;
			
			m_dirty=true;
			m_chart=chart;
			
			updateUI();
			repaint();
		}
		
		public void paintContent(Graphics g) {
			if (m_chart!=null)
				m_chart.draw((Graphics2D)g, m_chartArea);
		}
		
		public Dimension getContentSize() {
			if (m_chart!=null) {
				Dimension size=m_baseSize;
				if (m_dirty) {
					Rectangle visRect=getVisibleRect();
					if (visRect!=null && visRect.width>50 && visRect.height>50) {
						double scale=Math.min(visRect.getHeight()/size.getHeight(),visRect.getWidth()/size.getWidth());
						
						size.width=(int)(size.getWidth()*scale);
						size.height=(int)(size.getHeight()*scale);

						m_dirty=false;
						repaint();
					}
				}
				m_chartArea.setSize(size);
				
				return size;
			}
			else
				return super.getContentSize();
		}
	}

	@Override
	protected Component getFocusComponent() {
		return m_chartComponent;
	}
}