/*
 *  log.c: Log generation
 *
 *  Copyright (C) 1997-2005 John Coppens (john@jcoppens.com)
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2 of
 *  the License, or (at your option) any later version.
 *
 *  This program 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 program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gtk/gtk.h>
#include <complex.h>

#include "element.h"
#include "support.h"
#include "main.h"
#include "global.h"
#include "log.h"

#define res_hdrfmt      "   %9.*f MHz    "

GtkTreeView	*logview = NULL;

struct {
  int nr_lds, nr_els, *eltype;
  double *freq;
  complex *val, *elval, *load;
  GtkListStore *store;
} loglist = {
  0, 0, 0,
  NULL,
  NULL
};


void
loglist_initialize(GtkTreeView *tview)
{
  GtkTreeViewColumn *col;
  GtkCellRenderer *renderer;
  GtkTreeIter iter;
  int c;

  logview = tview;
  loglist.store = gtk_list_store_new(LOG_COLS,
		G_TYPE_STRING,
		G_TYPE_STRING,
		G_TYPE_STRING);
  gtk_tree_view_set_model(GTK_TREE_VIEW(logview),
			GTK_TREE_MODEL(loglist.store));
  g_object_unref(loglist.store);

  renderer = gtk_cell_renderer_text_new();
  gtk_object_set(GTK_OBJECT(renderer),
		"font", pref.results_font,
		"height", 16,
		NULL);
  col = gtk_tree_view_column_new_with_attributes("",
		renderer,
		"text", LOG_ELEM,
		NULL);
  gtk_tree_view_append_column(GTK_TREE_VIEW(logview), col);

  renderer = gtk_cell_renderer_text_new();
  gtk_object_set(GTK_OBJECT(renderer),
		"font", pref.results_font,
		"height", 16,
		NULL);
  col = gtk_tree_view_column_new_with_attributes("",
		renderer,
		"text", LOG_Z_Y,
		NULL);
  gtk_tree_view_append_column(GTK_TREE_VIEW(logview), col);

  renderer = gtk_cell_renderer_text_new();
  gtk_object_set(GTK_OBJECT(renderer),
		"font", pref.results_font,
		"height", 16,
		NULL);
  col = gtk_tree_view_column_new_with_attributes("",
		renderer,
		"text", LOG_RESULT,
		NULL);
  gtk_tree_view_append_column(GTK_TREE_VIEW(logview), col);
}


void
loglist_create(int nr_lds, int nr_els)
{
  if (loglist.val) g_free(loglist.val);
  loglist.val = malloc(sizeof(complex) * nr_lds * nr_els);
  loglist.elval = malloc(sizeof(complex) * nr_lds * nr_els);
  loglist.eltype = malloc(sizeof(int) * nr_els);
  loglist.freq  = malloc(sizeof(double) * nr_lds);
  loglist.load  = malloc(sizeof(complex) * nr_lds);
  loglist.nr_lds = nr_lds;
  loglist.nr_els = nr_els;
}


void
loglist_set_impedance(int ldnr, int elnr,
		complex el_imp, complex imp, int type)
{
  loglist.elval[elnr * loglist.nr_lds + ldnr] = imp;
  loglist.val[elnr * loglist.nr_lds + ldnr] = imp;
  loglist.eltype[elnr] = type;
}


void
loglist_set_load(int ldnr, double freq, complex imp)
{
  loglist.freq[ldnr] = freq;
  loglist.load[ldnr] = imp;
}


void
loglist_show(void)
{
  GtkTreeIter iter;
  GtkTreeViewColumn *col;
  GtkWidget *w;
  gboolean is_imp = TRUE;
  char bff[50], elref[10], row[300], *prow, *trow;
  int ld, el;
  complex c;

  if (number_loads() == 0) return;
  gtk_list_store_clear(loglist.store);

  // Element number column header
  prow = g_strdup_printf("<span font_desc=\"%s\">%s</span>",
		pref.results_font, _("Elem"));
  col = gtk_tree_view_get_column(logview, LOG_ELEM);
  w = gtk_label_new("");
  gtk_widget_show(w);
  gtk_label_set_markup(GTK_LABEL(w), prow);
  gtk_tree_view_column_set_widget(col, w);
  g_free(prow);

  // Z/Y mode column header 
  prow = g_strdup_printf("<span font_desc=\"%s\">%s</span>",
		pref.results_font, _("Z/Y"));
  col = gtk_tree_view_get_column(logview, LOG_Z_Y);
  w = gtk_label_new("");
  gtk_widget_show(w);   
  gtk_label_set_markup(GTK_LABEL(w), prow);
  gtk_tree_view_column_set_widget(col, w);
  g_free(prow);

  // Results column header
  prow = g_strdup_printf("<span font_desc=\"%s\">", pref.results_font);
  trow = prow;
  for (ld = 0; ld < loglist.nr_lds; ld++) {
    sprintf(bff, "   %11.*f MHz    ", pref.prec_mhz, loglist.freq[ld]);
    prow = g_strconcat(prow, bff, NULL);
    g_free(trow);
    trow = prow;
  }
  prow = g_strconcat(prow, "</span>");
  col = gtk_tree_view_get_column(logview, LOG_RESULT);
  w = gtk_label_new("");
  gtk_widget_show(w);
  gtk_label_set_markup(GTK_LABEL(w), prow);
  gtk_tree_view_column_set_widget(col, w);
  g_free(trow); g_free(prow);

  // And now the actual results

  // First a line with the load impedances
  prow = strdup("");
  trow = prow;
  for (ld = 0; ld < loglist.nr_lds; ld++) {
    c = loglist.load[ld];
    sprintf(bff, "%10.3f%+10.3f%s ", creal(c), cimag(c), pref.complex_sfx);
    prow = g_strconcat(prow, bff, NULL);
    g_free(trow);
    trow = prow;
  }
  gtk_list_store_append(loglist.store, &iter);
  gtk_list_store_set(loglist.store, &iter,
		LOG_ELEM, _("Load"),
		LOG_Z_Y, _("Z"),
                LOG_RESULT, prow,
                -1);
  g_free(prow);

  // Then, for each element:

  for (el = 0; el < loglist.nr_els; el++) {
    switch (loglist.eltype[el]) {
      case ELT_ZY:
	is_imp = !is_imp;
        break;
    }

    // First show the element value
    prow = strdup("");
    trow = prow;
    for (ld = 0; ld < loglist.nr_lds; ld++) {
      c = loglist.elval[el * loglist.nr_lds + ld]; 
      sprintf(bff, "%10.3f%+10.3f%s ", creal(c), cimag(c), pref.complex_sfx);
      prow = g_strconcat(prow, bff, NULL);
      g_free(trow);
      trow = prow;
    }
    sprintf(elref, _("El %d"), el+1);
    gtk_list_store_append(loglist.store, &iter);
    gtk_list_store_set(loglist.store, &iter,
		LOG_ELEM, elref,
		LOG_RESULT, loglist.eltype[el] != ELT_ZY ? prow : "",
		-1);
    g_free(prow);

    // Then show the circuit impedance/admittance
    prow = strdup("");
    trow = prow;
    for (ld = 0; ld < loglist.nr_lds; ld++) {
      c = loglist.val[el * loglist.nr_lds + ld];
      if (is_imp || pref.always_imp) {
        sprintf(bff, "%10.*f%+10.*f%s ", 
		pref.prec_imp, creal(c), pref.prec_imp, cimag(c),
		pref.complex_sfx);
      } else {
	c = pref.chart_z0*pref.chart_z0/c;
	sprintf(bff, "%10.*f%+10.*f%s ",
		pref.prec_adm, creal(c), pref.prec_adm, cimag(c),
		pref.complex_sfx);
      }
      prow = g_strconcat(prow, bff, NULL);
      g_free(trow);
      trow = prow;
    }
    gtk_list_store_append(loglist.store, &iter);
    gtk_list_store_set(loglist.store, &iter,
		LOG_ELEM, "",
		LOG_Z_Y, is_imp ? _("Z:") : _("Y:"),
		LOG_RESULT, prow, -1);
    g_free(prow);
  }
}


void
loglist_export(void)
{
  int ld, el;
  complex c;
  gboolean is_imp = TRUE;
  FILE *resf;

  if (!loglist.val) {
    ok_dialog(_("Warning"), _("No data have been calculated yet!"));
    return;
  }

  if (run_filedialog(_("Result export:"), pref.last_ps_file, "*.txt")) {
    if (g_file_test(pref.last_ps_file, G_FILE_TEST_EXISTS)) {
      if (ok_cancel_dialog(_("Confirmation"), 
          _("This file already exists.\n"
	    "Pressing Ok will overwrite it.")) == 1) return;
    }
  } else
    return;

  resf = fopen(pref.last_ps_file, "w");

  fprintf(resf, _("     "));
  for (ld = 0; ld < loglist.nr_lds; ld++) {
    fprintf(resf, res_hdrfmt, pref.prec_mhz, loglist.freq[ld]);
  }
  fprintf(resf, "\n");

  fprintf(resf, _("     "));
  for (ld = 0; ld < loglist.nr_lds; ld++) {
    c = loglist.load[ld];  
    fprintf(resf, "%10.3f%+10.3f%s ", creal(c), cimag(c), pref.complex_sfx);
  }
  fprintf(resf, "\n");

  for (el = 0; el < loglist.nr_els; el++) {
    switch (loglist.eltype[el]) {
      case ELT_ZY:
	is_imp = !is_imp;
	break;
    }
    // first, the element impedance
    fprintf(resf, _("     "));
    for (ld = 0; ld < loglist.nr_lds; ld++) {
      c = loglist.elval[el * loglist.nr_lds + ld];
      fprintf(resf, "%10.3f%+10.3f%s ", creal(c), cimag(c), pref.complex_sfx);
    }
    fprintf(resf, "\n");
    // then the circuit impedance or admittance
    fprintf(resf, _("El %2d"), el+1);
    for (ld = 0; ld < loglist.nr_lds; ld++) {
      c = loglist.val[el * loglist.nr_lds + ld];
      if (is_imp || pref.always_imp) {
        fprintf(resf, "%10.*f%+10.*f%s ",
		creal(c), pref.prec_imp, cimag(c), pref.prec_imp,
		pref.complex_sfx);
      } else {
	c = pref.chart_z0*pref.chart_z0/c;
	fprintf(resf, "%10.*f%+10.*f%s ",
		creal(c), pref.prec_adm, cimag(c), pref.prec_adm,
		pref.complex_sfx);
      }
    }
    fprintf(resf, "\n");
  }
  fclose(resf);
}


syntax highlighted by Code2HTML, v. 0.9.1