#include <applicat.h>
#include <automask.h>
#include <defmask.h>
#include <progind.h>
#include "../ve/velib.h"

#include <doc.h>
#include <rdoc.h>

#include "pt0003.h"
#include "pt0003100a.h"


class TMaskPt00031 : public TAutomask
{
	TCursor * _cur;

protected:
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
	bool on_sheet_event(TOperable_field& o, TField_event e, long jolly);
	void update_sheet();
	void update_pagato(real & totale);
	void update_total();

public:
	TCursor & cursor() const { return *_cur;}
  TMaskPt00031();
  virtual ~TMaskPt00031();
};

TMaskPt00031::TMaskPt00031()
            : TAutomask("pt0003100a")
{
	TRelation * r = new TRelation(LF_DOC);
	r->file().set_curr(new TDocumento);
	_cur = new TCursor(r, "", 2);
	((TButton_field&) field(DLG_SAVEREC)).set_exit_key(K_ENTER);
}

TMaskPt00031::~TMaskPt00031()
{  
	delete _cur;
}             

bool TMaskPt00031::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
	const int id = o.dlg();
	switch (id)
	{
		case F_TOTPAGATO:
			if (e == fe_modify )
			{
				real totpagato = o.mask().get_real(F_TOTPAGATO);

				update_pagato(totpagato);
			}
			break;
		case F_NUM:
			if (e == fe_modify || e == fe_init)
				update_sheet();
			break;
		case F_ANNO:
		case F_CODCLI:
			if (e == fe_modify)
				update_sheet();
			break;
		case F_SHEET:
			return on_sheet_event(o, e, jolly);
			break;
		default:
			if (jolly > 0)
				return on_sheet_event(o, e, jolly);
			break;
	}
  return true;
}


void TMaskPt00031::update_total()
{
  real tot;
  TSheet_field& s = sfield(F_SHEET);
  const int postot = s.cid2index(F_PAGATO);
  FOR_EACH_SHEET_ROW_BACK(s, r, row)
    tot += real(row->get(postot));
  set(F_TOTPAGATO, tot);
}

bool TMaskPt00031::on_sheet_event(TOperable_field& o, TField_event e, long jolly)
{
  TMask& m = o.mask();
  switch (o.dlg())
  {
  case F_PAGATO:
    if (e == fe_modify)
			update_total();
    break;
  case F_PAGA:
    if (e == fe_button)
    {
      TMask& m = o.mask();
      if (m.get_real(F_PAGATO).is_zero())
        m.set(F_PAGATO, m.get(F_DAPAGARE));
      else
        m.reset(F_PAGATO);
			TSheet_field & s = *m.get_sheet();

			const int r = s.selected();

			s.row(r).add(m.get(F_PAGATO), 0);
			s.force_update(r);

			update_total();
    }
    break;
  case F_SHEET:
    switch(e)
    {
			case se_query_add:
				return false;
			case se_notify_modify:
				update_total();
				break;
			default:
				break;
    }
    
  default:
    break;
  }
  return true;
} 

void TMaskPt00031::update_sheet()
{
  TSheet_field& sheet = sfield(F_SHEET);
	const int olditems = sheet.items();

  sheet.destroy();
	reset(F_TOTPAGATO);
	TRectype from(_cur->relation()->curr());
	const long codcli = get_long(F_CODCLI);

	from.put(DOC_TIPOCF, "C");
	from.put(DOC_CODCF, codcli);
	from.put(DOC_ANNO, get(F_ANNO));
	from.put(DOC_PROVV, "D");

	TRectype to(from);
	TString filter;
	filter << "(CODNUM==\"" << get(F_NUM) << "\")&&(G1:TOTDOC>IMPPAGATO)";
	_cur->setfilter(filter);
	_cur->setregion(from, to);
	TDocumento & doc = (TDocumento &)_cur->curr();
	
	const long items = _cur->items();

  TProgind pi(items, "Caricamento fatture", true, true);

	for ((*_cur) = 0L; _cur->pos() < items; ++(*_cur))
	{
    if (!pi.addstatus(1))
      break;
    if (sheet.items() > 900)  // Anche troppe righe
	    break;
	
		TToken_string & row = sheet.row(-1);
		const real totdoc = doc.totale_doc();
	  const real acconto = doc.get_real(DOC_IMPPAGATO);
		const real da_pagare = totdoc - acconto;

	  row.cut(0);
    row.add("");
    row.add(da_pagare.string());
    row.add(totdoc.string());
    row.add(doc.get(DOC_NDOC));
    row.add(doc.get(DOC_DATADOC));
	}

  if (olditems == 0 && items == 0)
    return;
  sheet.force_update();
}

void TMaskPt00031::update_pagato(real & totpagato)
{
  TSheet_field& sheet = sfield(F_SHEET);
	const long items = sheet.items();
	int pospagato = sheet.cid2index(F_PAGATO);
	int posda_pagare = sheet.cid2index(F_DAPAGARE);

	for (int r = 0; r < items; r++)
	{
		TToken_string & row = sheet.row(r);
		const real da_pagare(row.get(posda_pagare));
		real pagato;

		if (totpagato > ZERO)
		{
			if (totpagato > da_pagare)
				pagato = da_pagare;
			else
				pagato = totpagato;
			totpagato -= pagato;
		}
		const TString s(pagato.string());

    row.add(s, pospagato);
	}
  sheet.force_update();
}

class TIncassoFatture0003 : public TSkeleton_application  
{
  virtual bool check_autorization() const { return false; }
  virtual const char * extra_modules() const {return "ve";}


protected:
  virtual void main_loop();

public:
  virtual ~TIncassoFatture0003() {}
};

void TIncassoFatture0003::main_loop()
{
	open_files(LF_DOC, LF_RIGHEDOC, 0);
  TMaskPt00031 m;

  while (m.run() == K_ENTER)
  {
		TSheet_field & s = m.sfield(F_SHEET);
		TCursor & c = m.cursor();
		
		const long items = c.items();
		int pospagato = s.cid2index(F_PAGATO);

		for (long pos = 0L; pos < items; pos++)
		{
			TToken_string row = s.row(pos);
			real val(row.get(pospagato));

			if (val != ZERO)
			{
				c = pos;
				TDocumento doc((TDocumento &)c.curr());
				real pagato = doc.get(DOC_IMPPAGATO);
				real val(row.get(pospagato));

				pagato += val;
				doc.put(DOC_IMPPAGATO, pagato);
				doc.rewrite();
			}
		}
  }
}

TIncassoFatture0003 & app() { return (TIncassoFatture0003&) main_app();}

int pt0003100(int argc, char* argv[])
{
  TIncassoFatture0003 a;
  a.run(argc, argv, "Incasso fatture");
  return 0;
}