/*************************************************************
 *      Program Solving the KNAPSACK problem 		     *
 *      Author Jakub Holy                                    *
 *      For the subject PAA, LS2002                          *
 *							     *
 *	Use: Read input file.				     *
 *************************************************************
 */
// 	$Id: ksack_in.cc.html,v 1.1.1.1 2003/11/08 13:19:49 aja Exp $

#include <stdlib.h>	// func exit()
#include "ksack_in.hh"

Item::Item( int weight, int cost ) {
  Item::cost = cost;
  Item::weight = weight;
} // Item const

// Item::Item() {
//   Item::cost = -1;
//   Item::weight = -1;
// } // Item const

//************************************************************************

/** Constructor
 * Open the text file with the task and load the 1st one
 * (load items, set fields)
 *
 * The file structure is:
 * task_id nr_items max_load weight cost weight cost ... ...
 */
KnapsackInput::KnapsackInput(const char *filename){
  // Initialize
  items = 0; nr_items=max_load=task_id=0;
  // Open the file for reading + test it's indeed opened
  file.open( filename );
  if (! file.is_open() ){
    cout << "Error opening file "<< filename <<".\n";
    exit(1);
  }//if error opening the file

  // Get the 1st task and set the class fields
  if (! loadNextTask()){
    cout << "Error: the input file "<< filename <<"  is empty.\n";
    exit(1);
  }//if the file is empty

}//constructor

/** Destructor
 *  Close the file, if opened.
 */
KnapsackInput::~KnapsackInput(){
  if (file.is_open() ) file.close();
}//dest

//DO!!!
// while !file.eof() ...;

//----------------------------------------------------------------  loadNextTask
/** 
 * Extract values for the next task, if some is left }if not eof).
 * @return false if there is no more tasks
 */
bool KnapsackInput::loadNextTask(void){
  assert( file.is_open() ); // make sure it's open

  // --- TRY to read the file ---
  // Read the 1st line: task_id nr_items max_load 
  file >> task_id >> nr_items >> max_load;
  // Test for .eof must be here after we tried to read, because
  // it returns true after the last read has failed.
  if( file.eof() ) return false;

  // Free the old items and its content
    if( items != 0 ){
    // Free the old items, if non null:
      for(int i=0;i < 4; i++){
	if( items[i] != 0){
	  delete items[i];
	  items[i] = 0;	// this is not Java,must be done manually
	}//if not null
      }//for all items
      // OK, now free items itself
      delete [] items;
      items = 0;
    }// if tems non null    

  // Initiate the items array
  items  = new Item*[nr_items];	// items=table of pointers to Item
  // Zero the table (init its content)
  for( int i=0; i<nr_items; i++ ){ items[i] = 0; }
 
  // Extract the items
  {
    int lweight, lcost;
    for(int i=0; i<nr_items; i++){
      // read weight and cost of one item
      file >> lweight >> lcost;
      // create a new Item from that and store it
      items[i] = new Item( lweight, lcost );
    }// while there are items
  }// extract items

  return true;
}//loadNextTask


//----------------------------------------------------------------  Getters
//bool KnapsackInput::getNextItem(Item *ptr){return false;}//getNextItem

/** Getters. */ 
int KnapsackInput::getTaskID(void){return task_id;}
int KnapsackInput::getNr_items(void){return nr_items;}//getNr_items
int KnapsackInput::getMax_load(void){return max_load;}//getMax_load

/** Return array of pointers to Item(s) of the task */
Item **KnapsackInput::getItems(void){ return items;}

//*********************************************************************************
//TEST - delete!!!!!!!:
// int main(int argc, char **argv){
//   KnapsackInput *in = new KnapsackInput("del.txt");
//   while ( in->loadNextTask() ){}
//   Item **items = in->getItems();
//   cout<< "Task "<< in->getTaskID()<< " with "<< in->getNr_items()<< endl;
//   for(int i=0; i< in->getNr_items(); i++)
//     cout<< "Item "<<i<<":"<<(items[i])->weight<<endl;
//   cout << "Done.\n";
//   return 0;
// }// main