package org.fda.graphdrawing.chart;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.fda.graphdrawing.ImageFormat;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLabelLocation;
import org.jfree.chart.title.TextTitle;
import org.jfree.ui.RectangleEdge;


/**
 *
 * @author Gokhan.Yavas
 * @author Linlin.Zhao
 */
public abstract class TwoDPlot {
    protected File file;
    protected ImageFormat fileFormat=null;
    protected int width=1200, height=800; // chart width and height
    protected String chartName="TmpPlot";    
    protected String xAxisName="X Axis", yAxisName="Y Axis"; // name of x axis and y axis
    protected String yAxisNumFormat=null, xAxisNumFormat = null;
    protected Font chartNameFont=new Font("Arial", Font.BOLD, 35);
    protected Font xAxisNameFont=new Font("Arial", Font.BOLD, 20);
    protected Font yAxisNameFont=new Font("Arial", Font.BOLD, 20);
    protected Font legendNameFont=new Font("Arial", Font.PLAIN, 20);
    protected Font xAxisTickMarkFont=new Font("Arial", Font.PLAIN, 15), yAxisTickMarkFont=new Font("Arial", Font.PLAIN, 15);
    protected double xAxisTickUnit, yAxisTickUnit;
    protected double upperMargin=0.45, lowerMargin=0.40, leftMargin= 0.01, rightMargin=0.01;
    protected double xAxisUpperBound, xAxisLowerBound;
    protected double yAxisUpperBound, yAxisLowerBound;
    protected Color plotBackgroundPaintColor=Color.WHITE;
    protected Color chartBackgroundPaintColor=Color.WHITE;
    protected Color verticalGridlineColor=Color.GRAY, horizontalGridlineColor=Color.GRAY;
    protected Color xAxisColor=Color.BLACK, xAxisTickLabelColor = Color.BLACK, yAxisColor=Color.BLACK, yAxisTickLabelColor = Color.BLACK;
    protected Color chartOutlineColor = Color.BLACK, plotOutlineColor = Color.BLACK;
    protected boolean chartNameIsVisible=true, legendIsVisible=true, legendFrameIsVisible=true, chartOutlineIsVisible=false, plotOutlineIsVisible=false, horizontalGridlineIsVisible=false, verticalGridlineIsVisible=false, yAxisIsVisible = true, xAxisIsVisible = true, xAxisTickLabelIsVisible = true, yAxisTickLabelIsVisible = true;
    protected boolean defaultColors=false, defaultShapes=true;
    protected RectangleEdge legendLocation=RectangleEdge.TOP;
    protected AxisLabelLocation xAxisLabelLocation=AxisLabelLocation.MIDDLE, yAxisLabelLocation=AxisLabelLocation.MIDDLE;

    protected List<TextTitle> legendText=new ArrayList();
    public void addLegendText(TextTitle t){
        legendText.add(t);
    }
    protected boolean setFormat(){
        for(ImageFormat format : ImageFormat.values())
            if(file.getName().endsWith(format.getExtension())){
                fileFormat = format;
                return true;
            }
        return false;
    }    
    protected void saveAsFile(JFreeChart chart){
        FileOutputStream out = null;
        try{
            
            if(file.getParentFile()!=null && !file.getParentFile().exists()){
                file.getParentFile().mkdirs();
            }
            out = new FileOutputStream(file);
            
            if (this.fileFormat == ImageFormat.png){
                ChartUtilities.writeChartAsPNG(out, chart, this.width, this.height);
            }else if (this.fileFormat==ImageFormat.jpeg){
                ChartUtilities.writeChartAsJPEG(out, chart, this.width, this.height);
            }else if (this.fileFormat==ImageFormat.pdf){
                writeChartAsPDF(out, chart, this.width, this.height);
            }
            out.flush();
        }catch(FileNotFoundException e){
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        }finally{
            if (out != null){
                try{
                    out.close();
                }catch(IOException e){
                }
            }
        }
    }
    protected void writeChartAsPDF(FileOutputStream output, JFreeChart chart, int width, int height) throws IOException{
        Rectangle pagesize = new Rectangle(width, height);
        Document document = new Document(pagesize, 50, 50, 50, 50);
        try {
            PdfWriter writer = PdfWriter.getInstance(document, output); 
            document.addAuthor("JFreeChart");
            document.addSubject(this.chartName);
            document.open(); 
            PdfContentByte cb = writer.getDirectContent();
            PdfTemplate tp = cb.createTemplate(width, height);
            Graphics2D g2 = tp.createGraphics(width, height); 
            Rectangle2D r2D = new Rectangle2D.Double(0, 0, width, height); 
            
            chart.draw(g2, r2D); 
            g2.dispose(); 
            cb.addTemplate(tp, 0, 0);
        } catch(DocumentException de) {
        }finally {
            document.close();
        }
    }
    
    public void setFileFormat(ImageFormat ff){
        try{
            this.fileFormat = ff;
        }catch(Exception e){
        }
    }
    
    public void setChartNameVisible(boolean cn){
        try{
            this.chartNameIsVisible = cn;
        }catch(Exception e){
        }
    }
    
    public void setChartName(String name){
        try{
            this.chartName = name;
        }catch(Exception e){
        }
    }
    
    public void setChartNameFont(Font cnf){
        try{
            this.chartNameFont = cnf;
        }catch(Exception e){
        }
    }
    
    public void setChartBackgroundColor(Color cc){
        try{
            this.chartBackgroundPaintColor = cc;
        }catch(Exception e){
        }
    }
    
    public void setChartOutlineIsVisible(boolean ov){
        try{
            this.chartOutlineIsVisible = ov;
        }catch(Exception e){
        }
    }
    
    public void setChartOutlineColor(Color coc){
        try{
            this.chartOutlineColor = coc;
        }catch(Exception e){
        }
    }
    
    public void setPlotBackgroundColor(Color pc){
        try{
            this.plotBackgroundPaintColor = pc;
        }catch(Exception e){
        }
    }
    
    public void setPlotOutlineIsVisible(boolean ov){
        try{
            this.plotOutlineIsVisible = ov;
        }catch(Exception e){
        }
    }
    
    public void setPlotOutlineColor(Color poc){
        try{
            this.plotOutlineColor= poc;
        }catch(Exception e){
        }
    }
    
    public void setLegendVisible(boolean lv){
        try{
            this.legendIsVisible = lv;
        }catch(Exception e){
        }
    }
    
    public void setLegendFrameVisible(boolean lfv){
        try{
            this.legendFrameIsVisible = lfv;
        }catch(Exception e){
        }
    }
    
    public void setLegendNameFont(Font lnf){
        try{
            this.legendNameFont = lnf;
        }catch(Exception e){
        }
    }
    
    public void setWidthAndHeight(int w, int h){
        try{
            this.width = w;
            this.height = h;
        }catch(Exception e){
        }
    }
    
    public void setVerticalGridLineVisible(boolean vgl){
        try{
            this.verticalGridlineIsVisible = vgl;
        }catch(Exception e){
        }
    }
    
    public void setHorizontalGridLineVisible(boolean hgl){
        try{
            this.horizontalGridlineIsVisible = hgl;
        }catch(Exception e){
        }
    }
    
    public void setVerticalGridlineColor(Color vgc){
        try{
            this.verticalGridlineColor = vgc;
        }catch(Exception e){
        }
    }
    
    public void setHorizontalGridlineColor(Color hgc ){
        try{
            this.horizontalGridlineColor = hgc;
        }catch(Exception e){
        }
    }
    
    public void setXAxisName(String x){
        try{
            this.xAxisName = x;
        }catch(Exception e){
        }
    }
    
    public void setYAxisName(String y){
        try{
            this.yAxisName = y;
        }catch(Exception e){
        }
    }
      
    public void setXAxisNameFont(Font xa){
        try{
            this.xAxisNameFont = xa;
        }catch(Exception e){
        }
    }
    
    public void setYAxisNameFont(Font ya){
        try{
            this.yAxisNameFont = ya;
        }catch(Exception e){
        }
    }
    
    public void setXAxisTickFont(Font xtf){
        try{
            this.xAxisTickMarkFont = xtf;
        }catch(Exception e){
        }
    }
    
    public void setYAxisTickFont(Font ytf){
        try{
            this.yAxisTickMarkFont = ytf;
        }catch(Exception e){
        }
    }
    
    public void setXAxisUpperBound(double xu) {
        try{
            this.xAxisUpperBound = xu;
        }catch(Exception e){
        }
    }
    
    public void setXAxisLowerBound(double xl) {
        try{
            this.xAxisLowerBound = xl;
        }catch(Exception e){
        }
    }
    
    public void setXAxisTickUnit(double xt){
        try{
            this.xAxisTickUnit = xt;
        }catch(Exception e){
        }
    }
    
    public void setYAxisUpperBound(double yu) {
        try{
            this.yAxisUpperBound = yu;
        }catch(Exception e){
        }
    }
    
    public void setYAxisLowerBound(double yl) {
        try{
            this.yAxisLowerBound = yl;
        }catch(Exception e){
        }
    }
    
    public void setYAxisTickUnit(double yt){
        try{
            this.yAxisTickUnit = yt;
        }catch(Exception e){
        }
    }
    
    
    public void setXAxisColor(Color xc){
        try{
            this.xAxisColor = xc;
        }catch(Exception e){
        }
    }
    
    public void setYAxisColor(Color yc){
        try{
            this.yAxisColor = yc;
        }catch(Exception e){
        }
    }
    
    public void setUseDefaultColors(boolean dc){
        try{
            this.defaultColors = dc;
        }catch(Exception e){
        }
    }
    
    public void setUseDefaultShapes(boolean ds){
        try{
            this.defaultShapes = ds;
        }catch(Exception e){
        }
    }
    
    public void setMargin(double um, double lm){
        try{
            this.upperMargin = um;
            this.lowerMargin = lm;
        }catch(Exception e){
        }
    }
    
    public void setYAxisNumFormat(String ynf){
        try{
            this.yAxisNumFormat = ynf;
        }catch(Exception e){
        }
    }
    
    public void setXAxisNumFormat(String xnf){
        try{
            this.xAxisNumFormat = xnf;
        }catch(Exception e){
        }
    }
    
    public void setXAxisTickLabelColor(Color xtc){
        try{
            this.xAxisTickLabelColor = xtc;
        }catch(Exception e){
        }
    }
    
    public void setYAxisTickLabelColor(Color ytc){
        try{
            this.yAxisTickLabelColor = ytc;
        }catch(Exception e){
        }
    }
    
    public void setLegendLocation(RectangleEdge ll){
        try{
            this.legendLocation = ll;
        }catch(Exception e){
        }
    }
    
    public void setXAxisLabelLocation(AxisLabelLocation xll){
        try{
            this.xAxisLabelLocation = xll;
        }catch(Exception e){
        }
    }
    
    public void setYAxisLabelLocation(AxisLabelLocation yll){
        try{
            this.yAxisLabelLocation = yll;
        }catch(Exception e){
        }
    }
    
    public void setLeftMargin(double lm){
        try{
            this.leftMargin = lm;
        }catch(Exception e){
        }
    }
    
    public void setRightMargin(double rm){
        try{
            this.rightMargin = rm;
        }catch(Exception e){
        }
    }
}
