// -*- c++ -*-
#ifndef LEMON_LP_SOLVER_BASE_H
#define LEMON_LP_SOLVER_BASE_H

///\ingroup misc
///\file

// #include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <map>
#include <limits>
// #include <stdio>
//#include <stdlib>

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <memory>
#include <utility>

//#include <lemon/invalid.h>
//#include <expression.h>
//#include <stp.h>
//#include <lemon/max_flow.h>
//#include <augmenting_flow.h>
//#include <iter_map.h>

using std::cout;
using std::cin;
using std::endl;

namespace lemon {
  
  template <typename _Value>
  class LpSolverBase {
    
    /*! @name Uncategorized functions and types (public members)
    */
    //@{
  public:

    //UNCATEGORIZED

    /// \e
    typedef _Value Value;
    /// \e 
    static const Value INF;
  public:
    /// \e
    LpSolverBase() { }
    /// \e
    virtual ~LpSolverBase() { }

    /*! @name Low level interface (protected members)
      Problem manipulating functions in the low level interface
    */
    //@{
  protected:

    //MATRIX MANIPULATING FUNCTIONS

    /// \e
    virtual int _addCol() = 0;
    /// \e
    virtual int _addRow() = 0;
    /// \e
    virtual void _eraseCol(int i) = 0;
    /// \e
    virtual void _eraseRow(int i) = 0;
    /// \e
    virtual void _setRowCoeffs(int i, 
			       const std::vector<std::pair<int, Value> >& coeffs) = 0;
    /// \e
    /// This routine modifies \c coeffs only by the \c push_back method.
    virtual void _getRowCoeffs(int i, 
			       std::vector<std::pair<int, Value> >& coeffs) = 0;
    /// \e
    virtual void _setColCoeffs(int i, 
			       const std::vector<std::pair<int, Value> >& coeffs) = 0;
    /// \e
    /// This routine modifies \c coeffs only by the \c push_back method.
    virtual void _getColCoeffs(int i, 
			       std::vector<std::pair<int, Value> >& coeffs) = 0;
    /// \e
    virtual void _setCoeff(int col, int row, Value value) = 0;
    /// \e
    virtual Value _getCoeff(int col, int row) = 0;
    //  public:
    //    /// \e
    //    enum Bound { FREE, LOWER, UPPER, DOUBLE, FIXED };
  protected:
    /// \e
    /// The lower bound of a variable (column) have to be given by an 
    /// extended number of type Value, i.e. a finite number of type 
    /// Value or -INF.
    virtual void _setColLowerBound(int i, Value value) = 0;
    /// \e
    /// The lower bound of a variable (column) is an 
    /// extended number of type Value, i.e. a finite number of type 
    /// Value or -INF.
    virtual Value _getColLowerBound(int i) = 0;
    /// \e
    /// The upper bound of a variable (column) have to be given by an 
    /// extended number of type Value, i.e. a finite number of type 
    /// Value or INF.
    virtual void _setColUpperBound(int i, Value value) = 0;
    /// \e
    /// The upper bound of a variable (column) is an 
    /// extended number of type Value, i.e. a finite number of type 
    /// Value or INF.
    virtual Value _getColUpperBound(int i) = 0;
    /// \e
    /// The lower bound of a linear expression (row) have to be given by an 
    /// extended number of type Value, i.e. a finite number of type 
    /// Value or -INF.
    virtual void _setRowLowerBound(int i, Value value) = 0;
    /// \e
    /// The lower bound of a linear expression (row) is an 
    /// extended number of type Value, i.e. a finite number of type 
    /// Value or -INF.
    virtual Value _getRowLowerBound(int i) = 0;
    /// \e
    /// The upper bound of a linear expression (row) have to be given by an 
    /// extended number of type Value, i.e. a finite number of type 
    /// Value or INF.
    virtual void _setRowUpperBound(int i, Value value) = 0;
    /// \e
    /// The upper bound of a linear expression (row) is an 
    /// extended number of type Value, i.e. a finite number of type 
    /// Value or INF.
    virtual Value _getRowUpperBound(int i) = 0;
    /// \e
    virtual void _setObjCoeff(int i, Value obj_coef) = 0;
    /// \e
    virtual Value _getObjCoeff(int i) = 0;
    
    //SOLUTION RETRIEVING

    /// \e
    virtual Value _getPrimal(int i) = 0;
    //@}
    


    /*! @name MIP functions and types (public members)
    */
    //@{
  protected:
   /// \e
    virtual void _setColCont(int i) = 0;
    /// \e
    virtual void _setColInt(int i) = 0;
    /// \e
    virtual Value _getMIPPrimal(int i) = 0;
    //@}
  };

} //namespace lemon

#endif //LEMON_LP_SOLVER_BASE_H
