#include <applicat.h>
#include <automask.h>
#include <execp.h>
#include <progind.h>
#include <recset.h>
#include <relation.h>
#include <reprint.h>

#include "mg3.h"
#include "mg3600.h"
#include "rmovmag.h"

////////////////////////////////////////////////////////
//	MASCHERA
////////////////////////////////////////////////////////
class TStampa_etich_art_mask : public TAutomask
{
protected:
  bool on_field_event(TOperable_field& o, TField_event e, long jolly);

public:
  TStampa_etich_art_mask();
  virtual ~TStampa_etich_art_mask() {}
};


bool TStampa_etich_art_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{ 
  bool ok = true;
/*  switch (o.dlg())
  {
  case :
    {

    }
    break;
  default: break;
  }*/
  return ok;
}


TStampa_etich_art_mask::TStampa_etich_art_mask()
								:TAutomask("mg3600")
{}


///////////////////////////////////////////////////////////////
//	RECORDSET
///////////////////////////////////////////////////////////////

class TStampa_etich_art_recordset : public TISAM_recordset
{
	int _ncopie;
	TRecnotype _current_row;

public:
  virtual bool move_to(TRecnotype pos);
  virtual TRecnotype items() const;
  virtual TRecnotype current_row() const;
	void set_filter(const TStampa_etich_art_mask& msk);

  TStampa_etich_art_recordset(const TString& sql) : TISAM_recordset(sql), _ncopie(1), _current_row(0L) { }
};

//metodo per caricare i valori nel recordset dalla maschera...fighissimo!!
void TStampa_etich_art_recordset::set_filter(const TStampa_etich_art_mask& msk)
{
		TVariant var;

		var = msk.get(F_DACODART);
		set_var("#DACODART", var);
		var = msk.get(F_ACODART);
		set_var("#ACODART", var);
		_ncopie = msk.get_int(F_QTA);
}

TRecnotype TStampa_etich_art_recordset::items() const
{
	return _ncopie * TISAM_recordset::items();
}

TRecnotype TStampa_etich_art_recordset::current_row() const
{
	return _current_row;
}

bool TStampa_etich_art_recordset::move_to(TRecnotype pos)
{
	_current_row = pos;
	const bool valid = _current_row < items();

	if (_ncopie > 1)
	{
		if (pos >= items())
			return false;
		pos /= _ncopie;
	}
	if (valid)
		TISAM_recordset::move_to(pos);
	else
	_current_row = 0L;
	return valid;
}

//////////

class TStampa_etich_mov_recordset : public TISAM_recordset
{
	TPointer_array _index;
	TRecnotype _current_row;

public:
  virtual bool move_to(TRecnotype pos);
  virtual TRecnotype items() const;
  virtual TRecnotype current_row() const;
	void set_filter(const TStampa_etich_art_mask& msk);
	TPointer_array & index() { return _index; }
  virtual void requery();


  TStampa_etich_mov_recordset(const TString& sql) : TISAM_recordset(sql), _current_row(0L) { }
};

//metodo per caricare i valori nel recordset dalla maschera...fighissimo!!
void TStampa_etich_mov_recordset::set_filter(const TStampa_etich_art_mask& msk)
{
		TVariant var;

		var = msk.get(F_DACODART);
		set_var("#DACODART", var);
		var = msk.get(F_ACODART);
		set_var("#ACODART", var);
		var = msk.get(F_DADATA);
		set_var("#DADATA", var);
		var = msk.get(F_ADATA);
		set_var("#ADATA", var);
		var = msk.get(F_CAUS);
		set_var("#CAUS", var);
		TCursor * c = cursor();
		requery();
}

TRecnotype TStampa_etich_mov_recordset::items() const
{
	return _index.items();
}

TRecnotype TStampa_etich_mov_recordset::current_row() const
{
	return _current_row;
}

bool TStampa_etich_mov_recordset::move_to(TRecnotype pos)
{
	_current_row = pos;
	const bool valid = _current_row < items();

	if (valid)
		TISAM_recordset::move_to(_index.get_long(pos) - 1);
	else
		_current_row = 0L;
	return valid;
}

bool build_index(const TRelation& rel, void* pJolly)
{
	TStampa_etich_mov_recordset * r = (TStampa_etich_mov_recordset *) pJolly;
	int ncopie = atoi(rel.curr().get(RMOVMAG_QUANT));
	const TRecnotype pos = r->cursor()->pos();

	if (ncopie > 0)
		for ( int i = 0; i < ncopie; i++)
			r->index().insert_long(pos + 1);
	return true;
}

void TStampa_etich_mov_recordset::requery()
{
	if (valid_cursor())
	{
//		TISAM_recordset::requery();
		TCursor * c = cursor();

		_index.destroy();
		c->scan(build_index, this);
	}
}

////////////////////////////////////////////////////////
//	REPORT
////////////////////////////////////////////////////////
class TStampa_etich_art_rep : public TReport
{
protected:
	virtual bool get_usr_val(const TString& name, TVariant& var) const;
  virtual bool set_recordset(const TString& query);

public:
	void set_filter(const TStampa_etich_art_mask& msk);
};

//metodo per il calcolo dei campi da calcolare (ma va'!) nel report
bool TStampa_etich_art_rep::get_usr_val(const TString& name, TVariant& var) const
{
	return TReport::get_usr_val(name, var);
}

bool TStampa_etich_art_rep::set_recordset(const TString& query)
{
  return TReport::set_recordset(new TStampa_etich_art_recordset(query));
}

void TStampa_etich_art_rep::set_filter(const TStampa_etich_art_mask& msk)
{
	((TStampa_etich_art_recordset *)recordset())->set_filter(msk);
}

////////////////////////////////////////////////////////

class TStampa_etich_mov_rep : public TReport
{
protected:
	virtual bool get_usr_val(const TString& name, TVariant& var) const;
  virtual bool set_recordset(const TString& query);

public:
	void set_filter(const TStampa_etich_art_mask& msk);
};

//metodo per il calcolo dei campi da calcolare (ma va'!) nel report
bool TStampa_etich_mov_rep::get_usr_val(const TString& name, TVariant& var) const
{
	return TReport::get_usr_val(name, var);
}

bool TStampa_etich_mov_rep::set_recordset(const TString& query)
{
  return TReport::set_recordset(new TStampa_etich_mov_recordset(query));
}

void TStampa_etich_mov_rep::set_filter(const TStampa_etich_art_mask& msk)
{
	((TStampa_etich_mov_recordset *)recordset())->set_filter(msk);
}


////////////////////////////////////////////////////////
//	APPLICAZIONE
////////////////////////////////////////////////////////
class TStampa_etich_art : public TSkeleton_application
{
protected:
  virtual void main_loop();
};


void TStampa_etich_art::main_loop()
{
	TStampa_etich_art_mask mask;

  while (mask.run() == K_ENTER)
  {
		//report e book dei report
		TReport_book book;
		if (mask.get(F_TIPOST) == "A")
		{
			TStampa_etich_art_rep rep;

			rep.load("mg3600a");
			rep.set_filter(mask);
			book.add(rep);
		}
		else
		{
			TStampa_etich_mov_rep rep;

			rep.load("mg3600b");
			rep.set_filter(mask);
			book.add(rep);
		}
		book.print_or_preview();	//stampa il book dei report
	}
}

int mg3600(int argc, char* argv[])
{
  TStampa_etich_art a;
  a.run(argc, argv, TR("Stampa etichette articoli"));
  return 0;
}