#include <about.h>
#include <applicat.h>
#include <colors.h>
#include <config.h>
#include <dongle.h>
#include <prefix.h>
#include <sqlset.h>
#include <toolfld.h>
#include <urldefid.h>
#include <utility.h>

///////////////////////////////////////////////////////////
// TAdavnced_property sheet
///////////////////////////////////////////////////////////

class TAdvanced_property_sheet : public TMask
{ 
  TProp_field* _pf;

protected:
  virtual long handler(WINDOW win, EVENT* e);
  void edit();
  void esporta();

public:
  void freeze(bool on) { _pf->freeze(on); }
  void add_cat(const char* prompt);
  void add_prop(const char* prompt, const char* value);
  void add_prop(const char* prompt, long value);
  bool curr_prop(TString& prop, TVariant& value);

  void set_read_only(bool ro = true);
	TAdvanced_property_sheet(const char* title = "", int width = 78, int height = 20);
};

long TAdvanced_property_sheet::handler(WINDOW win, EVENT* e)
{
  if (_pf != NULL)
  {
    switch (e->type)
    {
    case E_SIZE:
      if (win == _pf->win().parent())
        _pf->win().maximize();
      break;
    case E_CONTROL:
      switch(e->v.ctl.id)
      {
      case DLG_EDIT: edit(); return 0L;
      case DLG_EXPORT: esporta(); return 0L;
      default: break;
      }
      break;
    default:
      break;
    }
  }
  return TMask::handler(win, e);
}

void TAdvanced_property_sheet::add_cat(const char* prompt)
{
  _pf->set_property(prompt, (const char*)NULL, prompt);
}

void TAdvanced_property_sheet::add_prop(const char* prompt, const char* value)
{
  _pf->set_property(prompt, value, prompt);
}

void TAdvanced_property_sheet::add_prop(const char* prompt, long value)
{
  _pf->set_property(prompt, value, prompt);
}

static BOOLEAN export_cb(WINDOW pg, XVT_TREEVIEW_NODE node, void* jolly)
{
  char name[_MAX_PATH];
  if (xvt_prop_get_string(pg, node, name, sizeof(name)))
  {
    ostream& out = *(ostream*)jolly;
    char value[_MAX_PATH];
    if (xvt_prop_get_data(pg, node, value, sizeof(value))) 
      out << '\t' << name << '\t' << value << endl; // Property 
    else
      out << name << endl; // Category
  }
  return TRUE;
}

void TAdvanced_property_sheet::edit()
{
  TString name;
  TVariant value;
  if (_pf->current_property(name, value))
  {
    TFilename n = value.as_string();
    if (n.exist())
    {
      if (n.ends_with(".msk", true) || n.ends_with(".ini", true))
      {
        n.insert("notepad ");
        xvt_sys_execute(n, FALSE, FALSE);
      } else
      xvt_sys_goto_url(n, "open");
    }
  }
}

void TAdvanced_property_sheet::esporta()
{
  TString cap; get_caption(cap);
  for (char* buf = cap.get_buffer(); *buf; buf++)
  {
    switch (*buf)
    {
    case '?':
    case '(':
    case ')':
    case '/':
    case '\\':
    case '*': *buf = ' '; break;
    default :  break;
    }
  }
  cap.strip_spaces();
  if (cap.blank())
    cap = "export";
  TFilename name;
  name.tempdir(); name.add(cap); name.ext("xls");
  if (name.full()) // Dummy test
  {
    ofstream xls(name);
    _pf->for_each_property(export_cb, &xls);
  }
  if (name.exist())
    xvt_sys_goto_url(name, "open");
}

void TAdvanced_property_sheet::set_read_only(bool ro)
{
  xvt_prop_set_read_only(_pf->win().win(), NULL, ro);
}

TAdvanced_property_sheet::TAdvanced_property_sheet(const char* title, int width, int height)
: TMask(title && *title ? title : TR("Propriet�"), 1, width, height), _pf(NULL)
{
  add_button_tool(DLG_CANCEL, TR("Ritorna"), TOOL_CANCEL);
  add_button_tool(DLG_EXPORT, TR("Esporta"), TOOL_EXCEL);
  if (is_power_reseller(true))
    add_button_tool(DLG_EDIT, TR("Edit"), TOOL_EDIT);
  add_button_tool(DLG_HELP, TR("Help"), TOOL_HELP);

  _pf = new TProp_field(this);
  _pf->create(DLG_USER, 0, 0, 0, 0, page_win(0));
}

///////////////////////////////////////////////////////////
// TBasic_property sheet
///////////////////////////////////////////////////////////

class TBasic_property_sheet : public TArray_sheet
{
protected:
  virtual bool get_cell_colors(int row, int col, COLOR& fore, COLOR& back) const;

public:
  void add_cat(const char* cat);
  void add_prop(const char* prop, const char* val);
  void add_prop(const char* prop, long val);
  TBasic_property_sheet(const char* title, int width, int height);
};

bool TBasic_property_sheet::get_cell_colors(int r, int col, COLOR& fore, COLOR& back) const
{
  const TToken_string& riga = ((TBasic_property_sheet*)this)->row(r);
  const bool changed = riga.items() == 1;
  if (changed)
  {
    fore = FOCUS_COLOR;
    back = REQUIRED_BACK_COLOR;
    return true;
  }
  return changed;
}


void TBasic_property_sheet::add_cat(const char* cat)
{
  add(cat);
}

void TBasic_property_sheet::add_prop(const char* prop, const char* val)
{
  TToken_string r;
  r = prop; 
  r.add(val);
  add(r);
}

void TBasic_property_sheet::add_prop(const char* prop, long val)
{
  add_prop(prop, format("%ld", val));
}

TBasic_property_sheet::TBasic_property_sheet(const char* title, int width, int height) 
                     : TArray_sheet(-1, -1, width, height, title, format("@%d|@%d", width/4-2, 3*width/4-2))
{ }

///////////////////////////////////////////////////////////
// TProperty sheet
///////////////////////////////////////////////////////////

void TProperty_sheet::add_cat(const char* cat)
{
  if (_power)
    ((TAdvanced_property_sheet*)_ps)->add_cat(cat);
  else
    ((TBasic_property_sheet*)_ps)->add_cat(cat);
}

void TProperty_sheet::add_prop(const char* prop, const char* val)
{
  if (_power)
    ((TAdvanced_property_sheet*)_ps)->add_prop(prop, val);
  else
    ((TBasic_property_sheet*)_ps)->add_prop(prop, val);
}

void TProperty_sheet::add_prop(const char* prop, long val)
{
  if (_power)
    ((TAdvanced_property_sheet*)_ps)->add_prop(prop, val);
  else
    ((TBasic_property_sheet*)_ps)->add_prop(prop, val);
}

void TProperty_sheet::freeze(bool f)
{
  if (_power)
    ((TAdvanced_property_sheet*)_ps)->freeze(f);
}

void TProperty_sheet::set_read_only(bool ro)
{
  if (_power)
    ((TAdvanced_property_sheet*)_ps)->set_read_only(ro);
}

KEY TProperty_sheet::run()
{ return _ps->run(); }


TProperty_sheet::TProperty_sheet(const char* title, int width, int height)
{
  const int nAssYear = xvt_vobj_get_attr(NULL_WIN, ATTR_APPL_VERSION_YEAR);
  _power = nAssYear >= 2121;
  if (_power)
    _ps = new TAdvanced_property_sheet(title, width, height);
  else
    _ps = new TBasic_property_sheet(title, width, height);
}

TProperty_sheet::~TProperty_sheet()
{
  delete _ps;
}

///////////////////////////////////////////////////////////
// Finestra informazioni
///////////////////////////////////////////////////////////

class TInfo_mask : public TProperty_sheet
{ 
public:
	TInfo_mask();
};


TInfo_mask::TInfo_mask() : TProperty_sheet(TR("Informazioni"))
{
  freeze(true);

  const word ser_no = dongle().number();

  int year = 2121, release = 11, tag = 0, patch = 1;
	TString80 versione = "2121.11.00";
  if (main_app().get_version_info(year, release, tag, patch))
		versione.format("%d.%02d.%02d Patch %d", year, release, tag, patch);

  TString16 datamod;
  TFilename cmdline = main_app().argv(0);
  cmdline.ext("exe");
  if (cmdline.exist())
  {
    const time_t mtime = xvt_fsys_file_attr(cmdline, XVT_FILE_ATTR_MTIME);
    struct tm data; localtime_s(&data, &mtime);
    datamod.format("%02d-%02d-%04d", data.tm_mday, data.tm_mon+1, data.tm_year+1900);
  }
  TString80 stros, strwx, strcpu;
  xvt_sys_get_version(stros.get_buffer(), strwx.get_buffer(), stros.size());
  xvt_sys_get_host_name(strcpu.get_buffer(), strcpu.size());

  TString arg;
  for (int a = 0; a < main_app().argc(); a++)
	  arg << main_app().argv(a) << ' ';
  arg.trim();

  TConfig campoini(CONFIG_INSTALL, "Main");
  TConfig userini(CONFIG_GUI, "Printer");
 
  TString prot;
  const TDongleHardware dhw = dongle().hardware();
	switch (dhw)
	{
	case _dongle_hardlock: prot = "Hardlock"; break;
	case _dongle_eutron  : prot = "Eutron"; break;
	case _dongle_network : prot = dongle().server_name(); break;
  case _dongle_ssa     : prot = "SSA"; 
    if (fexist("ssa.ini"))
    {
      const TString& host = ini_get_string("ssa.ini", "", "SSA-PORT");
      if (host.full())
        prot << '@' << host;
    }
    break;                        
	default              : prot = TR("Nessuna");	break;
	}

  int type = campoini.get_int("Type", "Main");
  const char* tipo = NULL;
  switch (type)
  {
  case 1: tipo = TR("Postazione singola"); break;
  case 2: tipo = TR("Server"); break;
  case 3: tipo = TR("Client"); break;
  default:
    if (campoini.get_bool("TestDatabase"))
    {
      if (dhw == _dongle_network)
      {
        tipo = TR("Server");
        campoini.set("Type", type = 2);
      }
      else
        tipo = TR("Server o Postazione singola");
    }
    else
    {
      tipo = TR("Client");
      campoini.set("Type", type = 3);
    }
    break;
  }

  TFilename temp; temp.tempdir();
  TString strdb, strsql;
  {
    TISAM_recordset rs("");
    strdb = rs.driver_version();
  }
  {
    TSQL_recordset rs("");
    strsql = rs.driver_version();
  }

  add_cat(TR("Programma"));
	add_prop(TR("Versione"), versione);
  add_prop(TR("Data"), datamod);
	add_prop(TR("Linea di Comando"), arg);
	add_prop(TR("Utente"), user());

  add_cat(TR("Licenza"));
  add_prop(TR("Installazione"), tipo);
  add_prop(TR("Protezione"), prot);
	add_prop(TR("N. di serie"), ser_no);
  if (ser_no > 0)
  {
    add_prop(TR("Assistenza"), dongle().year_assist());
    Tdninst dninst;
    add_prop(TR("Controllo"), dninst.assist_year());
  }

  add_cat(TR("Area dati"));
  TFilename study = firm2dir(-1);
  add_prop(TR("Studio"), study);
  const long codditta = campoini.get_long("Firm", "Main");
  add_prop(TR("Ditta"), codditta);
  if (prefix_valid())
  {
    const TFirm& f = prefix().firm();
    add_prop(TR("Ragione Sociale"), f.ragione_sociale());
    add_prop(TR("Valuta"), f.codice_valuta());
  }
  else
    add_prop(TR("Ragione Sociale"), campoini.get("Company"));

  add_cat(TR("Dati Stazione"));
  add_prop(TR("Sistema Operativo"), stros);
	add_prop(TR("Utente"), user());
  add_prop(TR("Computer"), strcpu);

  TString16 strfree;
  const long mbfree = xvt_fsys_get_disk_free_space(study, 'M');
  if (mbfree > 8192)
    strfree.format("%ld Gb", mbfree/1024);
  else
    strfree.format("%ld Mb", mbfree);
	add_prop(TR("Spazio su disco"), strfree);
  add_prop(TR("File temporanei"), temp);
	
  TString printer;
  printer = userini.get("Name", "Printer");
	if (printer.blank())
		printer = TR("Nessuna");
	add_prop(TR("Stampante"), printer);

  add_cat(TR("Configurazioni"));
	add_prop(TR("Config locale"), campoini.name());
  add_prop(TR("Config studio"), study.add("studio.ini"));
  if (codditta > 0)
  {
    study = firm2dir(codditta);
    add_prop(TR("Config ditta"), study.add("ditta.ini"));
  }
	add_prop(TR("Config utente"), userini.name());
  study = firm2dir(-1); study.add("config"); study.add(strcpu); study.ext("ini");
  add_prop(TR("Config stazione"), study), 

  add_cat(TR("Librerie di supporto"));
  xvt_print_pdf_version(printer.get_buffer(), printer.size());
  add_prop(TR("Libreria DB"),  strdb);
  add_prop(TR("Libreria GUI"), strwx);
  add_prop(TR("Libreria PDF"), printer);
  add_prop(TR("Libreria SQL"), strsql);
#ifdef _MSC_VER
  const int cver = _MSC_VER / 100 - 6;
  const int csub = _MSC_VER % 100;
  add_prop(TR("Libreria C++"),  format("Microsoft Visual Studio %d.%d", cver, csub));
#endif

  set_read_only();
  freeze(false);
}

// About box: risposta alla opzione Informazioni del menu File
void about()
{
  TInfo_mask info;
	info.run();
}