#ifndef __MR2200_H
#define __MR2200_H

#include <applicat.h>
#include <colmask.h>
#include "mrplib.h"

#include "mr2100.h"
#include "mr2201.h"

const real MAXCAPACITY("999999999.99");
const int NO_PROPOSE=1000 ;

enum TMSP_mode {_actual_plan, _rescheduling, _stock_break};
enum TMSP_logic {_first_fit_logic, _JIT_logic, _uniform_logic};

class TSave_mask;
class TPrint_mask;
class TPlanning_mask : public TCalendar_mask
{
  friend TSave_mask;
  friend TPrint_mask;
  static  bool _week_complete;
  
  TMagazzini _magazzini;     
  long _standard_for;
  TDate _start_date;
  // quantità provenienti dai documenti "ordine":
  TMSP_constraints _constraints; 

  // quantità provenienti dai documenti "planning" (commesse):
  TMSP_lines _articles;       

  // quantità per il processo di nettificazione/sizing in caso di generazione dell'MSP
  TMRP_lines _mrp_articles;
  // proposte del sistema
  TMRP_lines _proposed_articles, _proposed_1stlevel;

  // capacità linea per linea
  TCRP_lines _capacities; 
  
  TSelect_color_mask _sel_color; 
  int _npr_pos;   
  
protected:
  enum Categoria_doc {_Doc_vincoli=1, _Doc_planning=2};

  bool is_page_crp() const {return curr_page()==4;}

  bool on_field_event(TOperable_field& o, TField_event e, long jolly);
  
  bool load_MRP_lines(TMSP_mode mode, int level=0, int row=-1);
  bool gross2net(TMSP_mode mode, bool lotsizing=FALSE);
  void add_MRP_bucket(TMRP_line& new_article, int nbucket, const real &curr_arts);
  // proposta automatica del sistema
  bool general_review(bool check_machine, bool check_human, bool useextralines, bool useextrahours,bool lotsizing, bool no_outcapacity, int  anticipomin,int  anticipomax, TMSP_mode mode, TMSP_logic logic, const char *msg );
  int insert_propose(bool verbose=FALSE) ;
  bool remove_propose(bool verbose=FALSE) ;
  void highlight(int row, int col, bool on) ;
  void add_or_sub_propose(char sign, bool scheduled=FALSE);

  void propose(int row = -1);
  void propose_1stJIT(TMSP_logic logic, bool check_m, bool check_h, int row);
  // controlli
  void check_articles();
  void check_capacities();
  // capacity review
  bool capacity_review(bool useextralines, bool useextrahours);
  TCRP_line *compute_capacity(TLinea_prod &lineaprod,  bool useextralines, bool useextrahours);

  TMSP_constraint* find_constraint(const TMSP_line& l,bool force_insert=FALSE);
  int find_constr_row(TMSP_constraint& c);

  bool test_art_row(int r, bool signal=TRUE);
  bool test_load_row(int r, bool signal=TRUE);
  int init_bucket0(TArticolo_giacenza &art, int r);
  bool pack_article_sheet(int r, int first, int last);

  bool do_test_art_row(int r, int first, int last, bool signal);
  void do_test_art_2ndlevel(TMSP_line2 *mspline, bool erase=FALSE);

  void copy_sheet_row(TToken_string & newrow, const TToken_string & row);

  void clear_sheets();
  void set_sheet_header();
  void fill_sheet();
  void enable_codes(int r, bool on = TRUE);
  void disable_codes(int r) {enable_codes(r,FALSE);}
  
  int salva_cella(int r, int b, TPlan_docs &doc_rows, TToken_string & save_opt);

  void create_browse1(TEdit_field& kfld, int level, short key_id, short des_id, const TCodart_livelli &cal);
  void create_browse2(TEdit_field& kfld, int level, short key_id, short des_id, const TCodart_livelli &cal);
  int create_codart_fields(int x, int y, short key_id, short des_id);
  void init();
  // costruttore per la derivazione
  TPlanning_mask(const char * name);

public:
  static void get_week_year(const TDate &d, int &week, int &year);

public:
  bool on_savefields_event(long jolly);

  void msprow2codes(TToken_string &row, long &clifor, TCodice_articolo &art ,
    TString & liv, TString & mag, TString & magcoll, TString & imp, TString & lin, TString &  um);
  void crprow2codes(TToken_string &row, TString & imp, TString & lin, long &clifor, TCodice_articolo &art ,
    TString & liv, TString &  um);
  TMRP_line* find_propose(long codcli, const char * codart,const char * liv,
      const char * codimp,const char * codlin,const char * mag, const char * magcoll,
        bool Force=FALSE);
  TMSP_line* find_article(long cli, const char *art, const char *liv, 
        const char *imp, const char *lin, const char *mag, const char *magc, 
        bool Force=FALSE)
    {return _articles.find(cli, art, liv, imp, lin, mag, magc, Force);}


  const TDate & starting_date() const;
  int days_per_bucket() const;
  bool bucket_mese() const;

  int bucket(const TDate& date) const;
  int round_date(TDate& date, bool up = FALSE, bool wrkday = TRUE) const;
  void round_field(TMask_field& fld, bool up = FALSE, bool wrkday = TRUE) const;

  int test_codnum(const TCodice_numerazione& num) const;
  bool test_tipodoc_num( const TSheet_field &sheet_num , const TSheet_field &sheet_type) ;

  int test_status(const TRectype& doc, int tipo) const;
  bool has_confirmed_status(const TRectype& doc, TToken_string &riga) const;
  bool has_confirmed_status(const TRectype &doc) const;
  bool has_confirmed_status(const char * codnum, const char *tipodoc, char stato) const;

  bool elabora();
  bool carica_documenti();
  int salva_documenti(TExceptions_array &excepts, TSheet_field & save_opt);
  bool find_exceptions(TExceptions_array &e, bool anticipi, bool posticipi, bool extra, bool stockbreak, bool codemiss, bool verbose=FALSE);
  // STAMPE E VIDEO
  void print_articles(int fromcol, int numcols, const char * row_filter);
  void print_capacities();
  void print_exceptions(TExceptions_array &excepts);

  static void print_except_header(TPrinter& pr);
  bool sortMSPsheet();
  bool sortCRPsheet();

  virtual bool is_acq_planning() { return FALSE;}
  TSelect_color_mask & sel() { return _sel_color; }
  TPlanning_mask();
  virtual ~TPlanning_mask() { }
};


class TPlanning_app : public TSkeleton_application
{
protected:
  TPlanning_mask *_m;
  virtual bool create();
  void openfiles() ;
  virtual TPlanning_mask& mask() {return *_m;}
  virtual void main_loop();
  virtual bool firm_change_enabled() const { return FALSE; }
public:
  TPlanning_app() : _m(NULL) {}
};


#endif // __MR2200_H