/* gtkplotbox - box plots widget for gtk+
 * Copyright 1999-2001  Adrian E. Feiguin <feiguin@ifir.edu.ar>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <gtk/gtk.h>
#include "gtkplot.h"
#include "gtkplot3d.h"
#include "gtkplotdata.h"
#include "gtkplotcandle.h"
#include "gtkpsfont.h"

static void gtk_plot_candle_class_init 	(GtkPlotCandleClass *klass, gpointer unused);
static void gtk_plot_candle_init 	(GtkPlotCandle *data, gpointer unused);
static void gtk_plot_candle_draw_legend	(GtkPlotData *data, 
					 gint x, gint y);
static void gtk_plot_candle_draw_symbol	(GtkPlotData *data,
                                     	 gdouble x, 
					 gdouble y, 
					 gdouble z, 
					 gdouble a,
                                     	 gdouble dx, 
					 gdouble dy, 
					 gdouble dz, 
					 gdouble da);

gint roundint (gdouble x);


static GtkPlotDataClass *parent_class = NULL;

GType
gtk_plot_candle_get_type (void)
{
  static GType data_type = 0;

  if (!data_type)
    {
      GTypeInfo data_info =
      {
	sizeof (GtkPlotCandleClass),
	NULL,
	NULL,
	(GClassInitFunc) gtk_plot_candle_class_init,
	NULL,
	NULL,
	sizeof (GtkPlotCandle),
	0,
	(GInstanceInitFunc) gtk_plot_candle_init,
      };

      data_type = g_type_register_static (gtk_plot_data_get_type (),
                                          "GtkPlotCandle", &data_info, 0);
    }
  return data_type;
}

static void
gtk_plot_candle_class_init (GtkPlotCandleClass *klass, gpointer unused)
{
  GtkPlotDataClass *data_class;

  parent_class = g_type_class_peek (gtk_plot_data_get_type ());

  data_class = (GtkPlotDataClass *) klass;

  data_class->draw_legend = gtk_plot_candle_draw_legend;
  data_class->draw_symbol = gtk_plot_candle_draw_symbol;
/*
  data_class->draw_data = gtk_plot_candle_draw;
*/
}


static void
gtk_plot_candle_init (GtkPlotCandle *dataset, gpointer unused)
{
  GdkRGBA black, white;
  GtkPlotArray *dim;

  gdk_rgba_parse(&black, "black");
  gdk_rgba_parse(&white, "white");

  GTK_PLOT_DATA(dataset)->symbol.symbol_style = GTK_PLOT_SYMBOL_FILLED;
  GTK_PLOT_DATA(dataset)->symbol.color = white;
  GTK_PLOT_DATA(dataset)->line.line_style = GTK_PLOT_LINE_SOLID;
  GTK_PLOT_DATA(dataset)->line.line_width = 1;
  GTK_PLOT_DATA(dataset)->line.color = black;
  
  dim = gtk_plot_data_find_dimension(GTK_PLOT_DATA(dataset), "y");
  gtk_plot_array_set_label(dim, "Open");
  gtk_plot_array_set_description(dim, "Open");
  dim = gtk_plot_data_find_dimension(GTK_PLOT_DATA(dataset), "z");
  gtk_plot_array_set_required(dim, TRUE);
  gtk_plot_array_set_label(dim, "Close");
  gtk_plot_array_set_description(dim, "Close");
  dim = gtk_plot_data_find_dimension(GTK_PLOT_DATA(dataset), "dy");
  gtk_plot_array_set_required(dim, TRUE);
  gtk_plot_array_set_label(dim, "Min");
  gtk_plot_array_set_description(dim, "Minimum");
  dim = gtk_plot_data_find_dimension(GTK_PLOT_DATA(dataset), "dz");
  gtk_plot_array_set_required(dim, TRUE);
  gtk_plot_array_set_label(dim, "Max");
  gtk_plot_array_set_description(dim, "Maximum");
}

GtkWidget*
gtk_plot_candle_new (void)
{
  GtkWidget *widget;

  widget = g_object_new (gtk_plot_candle_get_type (), NULL);

  return (widget);
}

static void
gtk_plot_candle_draw_symbol(GtkPlotData *dataset,
                         gdouble x, gdouble y, gdouble z, gdouble a,
                         gdouble dx, gdouble dy, gdouble dz, gdouble da)
{
  GtkPlot *plot;
  gdouble px, py, pz, ex, ey, ez;
  gdouble x1 = 0.0, y1 = 0.0, width = 0.0, height = 0.0;
  gdouble m;
  gboolean filled;
  gdouble a_scale;


  g_return_if_fail(GTK_IS_PLOT_CANDLE(dataset));

  g_return_if_fail(dataset->plot != NULL);

  plot = dataset->plot;

  a_scale = gtk_plot_data_get_a_scale(dataset);
  m = plot->magnification * a_scale;

  gtk_plot_pc_set_lineattr (plot->pc, dataset->symbol.border.line_width, 
                            0, 0, 0);
  gtk_plot_pc_set_dash (plot->pc, 0, 0, 0); 

  if(x >= plot->xmin && x <= plot->xmax){
    if(GTK_IS_PLOT3D(plot)){
    }else if(dataset->show_zerrbars){
       gtk_plot_pc_set_color(plot->pc, &dataset->symbol.border.color);
       gtk_plot_get_pixel(plot, x, y, &px, &py);
       gtk_plot_get_pixel(plot, x, z, &px, &pz);
       width = m * dataset->symbol.size / 2;
       x1 = px - width;
       y1 = MIN(py, pz);
       filled = z < y;
       height = fabs(py - pz);

       gtk_plot_get_pixel(plot, x, dy, &ex, &ey);
       gtk_plot_get_pixel(plot, x, dz, &ex, &ez);

       gtk_plot_pc_draw_line(plot->pc, px, py, px, ey);
       gtk_plot_pc_draw_line(plot->pc, px, pz, px, ez);

       if(!filled && dataset->symbol.symbol_style != GTK_PLOT_SYMBOL_EMPTY){
         gtk_plot_pc_set_color(plot->pc, &plot->background);
         gtk_plot_pc_draw_rectangle (plot->pc,
                                     TRUE,
                                     x1, y1, width * 2, height);
       }


       if(dataset->symbol.symbol_style == GTK_PLOT_SYMBOL_EMPTY){
         GtkPlotPoint lines[4];
         gtk_plot_pc_set_color(plot->pc, &dataset->symbol.color);
         lines[0].x = px - width;
         lines[0].y = py;
         lines[1].x = px;
         lines[1].y = py;
         lines[2].x = px;
         lines[2].y = pz;
         lines[3].x = px + width;
         lines[3].y = pz;
         gtk_plot_pc_draw_lines(plot->pc, lines, 4);
       } else {
         if(filled){
           gtk_plot_pc_set_color(plot->pc, &dataset->symbol.color);
           gtk_plot_pc_draw_rectangle (plot->pc,
                                       TRUE,
                                       x1, y1, width * 2, height);
         }
         gtk_plot_pc_set_color(plot->pc, &dataset->symbol.border.color);
         gtk_plot_pc_draw_rectangle (plot->pc,
                                     FALSE,
                                     x1, y1, width * 2, height);
       }

    }  
  }

}


static void
gtk_plot_candle_draw_legend(GtkPlotData *data, gint x, gint y)
{
  GtkPlot *plot = NULL;
  GtkPlotText legend;
  GtkAllocation allocation;
  GdkRectangle area;
  gint lascent, ldescent, lheight, lwidth;
  gdouble m;

  g_return_if_fail(data->plot != NULL);
  g_return_if_fail(GTK_IS_PLOT(data->plot));
  if(!gtk_widget_get_realized(GTK_WIDGET(data->plot))) return;

  plot = data->plot;
  gtk_widget_get_allocation(GTK_WIDGET(plot), &allocation);
  area.x = allocation.x;
  area.y = allocation.y;
  area.width = allocation.width;
  area.height = allocation.height;

  m = plot->magnification;
  legend = plot->legends_attr;

  if(data->legend)
    legend.text = data->legend;
  else
    legend.text = (char *)"";

  gtk_plot_text_get_size(legend.text, legend.angle, legend.font,
                         roundint(legend.height * m), 
                         &lwidth, &lheight,
                         &lascent, &ldescent);


  legend.x = (gdouble)(area.x + x + roundint((plot->legends_line_width + 4) * m))
             / (gdouble)area.width;
  legend.y = (gdouble)(area.y + y + lascent) / (gdouble)area.height;

  gtk_plot_draw_text(plot, legend);

  gtk_plot_pc_set_lineattr (plot->pc, data->symbol.border.line_width, 0, 0, 0);
  gtk_plot_pc_set_dash (plot->pc, 0, 0, 0);

  gtk_plot_pc_set_color(plot->pc, &data->symbol.color);

  if(data->symbol.symbol_style == GTK_PLOT_SYMBOL_EMPTY){
    gtk_plot_pc_draw_line(plot->pc, 
                          x,  
                          y + (lascent + ldescent) / 2,
                          x + roundint(plot->legends_line_width * m), 
                          y + (lascent + ldescent) / 2); 
  } else {
    gtk_plot_pc_draw_rectangle(plot->pc, TRUE, 
                               x, y,
                               roundint(plot->legends_line_width * m), 
                               lascent + ldescent);
    gtk_plot_pc_set_color(plot->pc, &data->symbol.border.color);
    gtk_plot_pc_draw_rectangle(plot->pc, FALSE, 
                               x, y,
                               roundint(plot->legends_line_width * m), 
                               lascent + ldescent);

  }

}

