#ifndef __FILE_GSM_H_SEEN__
#define __FILE_GSM_H_SEEN__

/*-----------------------------------------------------------------------------

Copyright (C) 2005, 2006, 2008.

A. Ronald Gallant
Post Office Box 659
Chapel Hill NC 27514-0659
USA   

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 General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

-----------------------------------------------------------------------------*/

#include "libsnp.h"
#include "snp.h"
#include "libgsm.h"
#include "gsm_base.h"
#include "gsmusr.h"

namespace gsm {
    
  class gsmblocks {
  private:
    std::vector<std::string> history;
    std::vector<std::string> stat_parm_rhs;
    std::vector<std::string> stat_scale_rhs;
    std::vector<std::string> stat_groups_txt;
    std::vector<std::string> sci_parm_rhs;
    std::vector<std::string> sci_scale_rhs;
    std::vector<std::string> sci_incr_rhs;
    std::vector<std::string> sci_groups_txt;
    estblock  est_blk;
    datblock  dat_blk;
    statblock stat_blk;
    scl::realmat   stat_parm;
    scl::intvec    stat_mask;
    scl::realmat   stat_scale;
    libgsm::prop_def stat_prop_def; 
    std::vector<std::string> stat_alvec;
    sciblock  sci_blk;
    scl::realmat   sci_parm;
    scl::intvec    sci_mask;
    scl::realmat   sci_incr;
    scl::realmat   sci_scale;
    libgsm::prop_def sci_prop_def; 
    std::vector<std::string> sci_alvec;
  public:
    gsmblocks() { };
    bool set_blks(const std::vector<std::string>& pfvec, std::ostream& detail);
    bool read_blks(const char* filename, std::ostream& detail);
    bool write_blks
      (std::string parmfile, std::string prefix, std::string suffix) const;
    void set_stat_block(const statblock& stblk);
    void set_stat_parm(const scl::realmat& stparm);
    void set_sci_block(const sciblock& scblk);
    void set_sci_parm(const scl::realmat& scparm);
    const estblock& get_estblock() const {return est_blk;}
    const datblock& get_datblock() const {return dat_blk;}
    const statblock& get_statblock() const {return stat_blk;}
    const scl::realmat& get_stat_parm() const {return stat_parm;}
    const libgsm::prop_def get_stat_prop_def() const {return stat_prop_def;}
    const std::vector<std::string> get_stat_alvec() const {return stat_alvec;}
    const sciblock& get_sciblock() const {return sci_blk;}
    const scl::realmat& get_sci_parm() const {return sci_parm;}
    const libgsm::prop_def get_sci_prop_def() const {return sci_prop_def;}
    const std::vector<std::string> get_sci_alvec() const {return sci_alvec;}
  };
  
  // vecbuf is a container class that facilitates message passing

  class vecbuf {       
  private:
    INTEGER rows;    // Because of the '\0' termination character at
    INTEGER cols;    // the end of each row, size is rows*(cols+1).
    char*   blk;     
  public:
    vecbuf() : rows(0), cols(0), blk() { }
    vecbuf(INTEGER r, INTEGER c);
    vecbuf(std::vector<std::string> v, INTEGER c = 80);
    vecbuf(const vecbuf& vb);
    vecbuf& operator=(const vecbuf& vb);
    ~vecbuf() { delete[] blk; }
    void    resize(INTEGER r, INTEGER c);
    INTEGER get_rows() const { return rows; }
    INTEGER get_cols() const { return cols; }
    INTEGER size() const { return rows*(cols+1); }
    char* get_ptr() { return blk; }
    std::vector<std::string> get_vec();
  };

  class sci_summary {
  private:
    INTEGER N;
    estblock est_blk;
    libgsm::sci_val mode;
    scl::realmat sci_parm_sum;
    scl::realmat sci_parm_ctr;
    scl::realmat sci_parm_sse;
    scl::realmat sci_func_sum;
    scl::realmat sci_func_ctr;
    scl::realmat sci_func_sse;
    scl::realmat stat_parm_sum;
    scl::realmat stat_parm_ctr;
    scl::realmat stat_parm_sse;
    scl::realmat stat_func_sum;
    scl::realmat stat_func_ctr;
    scl::realmat stat_func_sse;
  public:
    sci_summary(estblock eb) : N(0), est_blk(eb) { }  
    void update(const scl::realmat& sci_parm_chain, 
           const scl::realmat& sci_func_chain,
           const scl::realmat& stat_parm_chain, 
           const scl::realmat& stat_func_chain,
           const libgsm::sci_val& sci_mode);
     bool write(std::string prefix);
  };

  class assess_summary {
  private:
    INTEGER N;
    estblock est_blk;
    libgsm::stat_val mode;
    scl::realmat assess_stat_parm_sum;
    scl::realmat assess_stat_parm_ctr;
    scl::realmat assess_stat_parm_sse;
    scl::realmat assess_stat_func_sum;
    scl::realmat assess_stat_func_ctr;
    scl::realmat assess_stat_func_sse;
  public:
    assess_summary(estblock eb) : N(0), est_blk(eb) { }
    void update(const scl::realmat& assess_stat_parm_chain, 
           const scl::realmat& assess_stat_func_chain,
           const libgsm::stat_val& sci_mode);
     bool write(std::string prefix);
  };

}

#endif
