//===========================================================================//
// This file is part of the Decomp Solver Framework.                         //
//                                                                           //
// Decomp is distributed under the Common Public License as part of the      //
// COIN-OR repository (http://www.coin-or.org).                              //
//                                                                           //
// Author: Matthew Galati, Lehigh University                                 //
//                                                                           //
// Copyright (C) 2002-2007, Lehigh University, Matthew Galati, and Ted Ralphs//
// All Rights Reserved.                                                      //
//===========================================================================//

#ifndef DECOMP_SOLUTION_INCLUDED
#define DECOMP_SOLUTION_INCLUDED

class DecompSolution {
protected:
   /** Length of solution (number of columns). */
   int      m_size;

   /** Solution values. */
   double* m_values;

   /** Quality of solution (bound wrt to objective). */
   double   m_quality;

public:
   /** @name Helper functions (public). */

   /** Get length of solution. */
   inline const int getSize() const {
      return m_size;
   }

   /** Get solution values. */
   inline const double* getValues() const {
      return m_values;
   }

   /** Get quality of solution. */
   inline const double getQuality() const {
      return m_quality;
   }

public:
   virtual void print(ostream& os = cout) const {
      int i;
      os << setiosflags(ios::fixed | ios::showpoint)
         << setw(14);
      os << "-------------------------" << endl;

      for (i = 0; i < m_size; i++) {
         if (!UtilIsZero(m_values[i])) {
            os << setw(6) << i << " " << m_values[i] << endl;
         }
      }

      os << "-------------------------" << endl;
      os << resetiosflags(ios::fixed | ios::showpoint | ios::scientific);
   }

public:
   /** @name Copy Constructors */
   DecompSolution(const DecompSolution& source) :
      m_size(source.m_size),
      m_values(0),
      m_quality(source.m_quality) {
      m_values = new double[m_size];
      CoinAssertHint(m_values, "Error: Out of Memory");
      memcpy(m_values, source.m_values, m_size * sizeof(double));
   }
   DecompSolution& operator=(const DecompSolution& rhs) {
      if (this != &rhs) {
         m_size    = rhs.m_size;
         m_quality = rhs.m_quality;
         m_values = new double[m_size];
         CoinAssertHint(m_values, "Error: Out of Memory");
         memcpy(m_values, rhs.m_values, m_size * sizeof(double));
      }

      return *this;
   }

public:
   /** @name Constructor and Destructor */

   /** Default constructor. Takes size of solution. */
   DecompSolution() :
      m_size(0),
      m_values(0),
      m_quality(DecompInf) {
   }

   /** Constructor. */
   DecompSolution(const int      size,
                  const double* values,
                  const double   quality) :
      m_size(size),
      m_values(0),
      m_quality(quality) {
      CoinAssert(m_size > 0);
      m_values = new double[m_size];
      CoinAssertHint(m_values, "Error: Out of Memory");
      memcpy(m_values, values, m_size * sizeof(double));
   }

   virtual ~DecompSolution() {
      UTIL_DELARR(m_values);
   };
};

#endif
