// file: $isip/class/algo/DisplayData/dspd_05.cc
// version: $Id: dspd_05.cc 7653 2002-01-29 22:38:52Z gao $
//

// isip include files
//
#include "DisplayData.h"

// method: apply
//
// arguments:
//  Vector<AlgorithmData>& output: (output) output data
//  const Vector< CircularBuffer<AlgorithmData> >& input: (input) input data
//
// return: a boolean value indicating status
//
// this method calls the appropriate computation methods
//
boolean DisplayData::apply(Vector<AlgorithmData>& output_a,
			   const Vector< CircularBuffer<AlgorithmData> >&
			   input_a) {

  // determine the number of input channels and force the output to be
  // that number
  //
  long len = input_a.length();
  output_a.setLength(len);
  boolean res = true;
  
  // start the debugging output
  //
  displayStart(this);

  // loop over the channels and call the compute method
  //
  for (long c = 0; c < len; c++) {

    // display the channel number
    //
    displayChannel(c);

    // call the compute method to produce our nicely formatted output
    //
    res &= compute(output_a(c), input_a(c)(0));
    
    // possibly display the data. note that we only display if the
    // debug level is greater than brief (the default). for the
    // default mode, we call our own display routines in the compute
    // method.
    //
    if (debug_level_d > Integral::BRIEF) {
      display(output_a(c), input_a(c)(0), name());
    }
  }

  // finish the debugging output
  //
  displayFinish(this);

  // exit gracefully
  //
  return res;
}

// method: compute
//
// arguments:
//  AlgorithmData& output: (output) output data
//  const AlgorithmData& input: (input) input data
//
// return: logical error status
//
boolean DisplayData::compute(AlgorithmData& output_a,
			     const AlgorithmData& input_a) {

  // create a nice display of the data
  //
  if ((debug_level_d >= Integral::BRIEF) && shouldDisplayFrame()) {

    // for anything but a combination, just display the object
    //
    if (input_a.getDataType() != AlgorithmData::COMBINATION) {
      displayObject(input_a);
    }

    // for a combination we need to loop over elements
    //
    else {

      long len = input_a.getCombination().length();
      for (long i = 0; i < len; i++) {

	// produce a header for which element this is
	//
	String output(ELEMENT_HEADER_00);
	output.concat(i);
	output.concat(ELEMENT_HEADER_01);
	Console::put(output);

	// within indention, call the displayObject method
	//
	Console::increaseIndention();
	displayObject(input_a.getCombination()(i));
	Console::decreaseIndention();
      }
    }
  }

  // copy the data (note this also sets coef_type)
  //
  return output_a.assign(input_a);
}

// method: displayObject
//
// arguments:
//  const AlgorithmData& input: (input) input data
//
// return: logical error status
//
boolean DisplayData::displayObject(const AlgorithmData& input_a) const {

  String output;
  if (label_d.length() > 0) {
    output.assign(label_d);
    output.concat(LABEL_DELIM);
  }
  
  output.concat(prefix_d);
  
  if (input_a.getDataType() == AlgorithmData::VECTOR_FLOAT) {
    String num;
    input_a.getVectorFloat().get(num);
    output.concat(num);
    output.concat(suffix_d);
    Console::put(output);
  }
  else if (input_a.getDataType() == AlgorithmData::VECTOR_COMPLEX_FLOAT) {
    String num;
    input_a.getVectorComplexFloat().get(num);
    output.concat(num);
    output.concat(suffix_d);
    Console::put(output);
  }
  else if (input_a.getDataType() == AlgorithmData::MATRIX_FLOAT) {

    long len = output.length();

    long nrow = input_a.getMatrixFloat().getNumRows();

    if (nrow == 0) {
      output.concat(EMPTY_MATRIX);
      output.concat(suffix_d);
      Console::put(output);
      return true;
    }

    output.concat(MATRIX_START);
    
    String num;
    VectorFloat row_vec;
    input_a.getMatrixFloat().getRow(row_vec, 0);
    row_vec.get(num, MATRIX_DELIM);
    output.concat(num);
    output.concat(MATRIX_END);

    if (nrow == 1) {
      output.concat(suffix_d);
      Console::put(output);
      return true;
    }
    else {
      Console::put(output);
    }
    
    String blank(len + MATRIX_START.length());
    for (long j = 0; j < len; j++) {
      blank(j) = MATRIX_DELIM(0);
    }
    blank(len) = (unichar)NULL;
    blank.concat(MATRIX_START);
    
    for (long i = 1; i < nrow; i++) {
      output.assign(blank);
      input_a.getMatrixFloat().getRow(row_vec, i);
      row_vec.get(num, MATRIX_DELIM);
      output.concat(num);
      output.concat(MATRIX_END);

      if (i == (nrow - 1)) {
	output.concat(suffix_d);
      }
      Console::put(output);
    }
  }
  else {
    return Error::handle(name(), L"displayObject", Error::ARG,
			 __FILE__, __LINE__);
  }

  // exit gracefully
  //
  return true;
}

// method: shouldDisplayFrame
//
// arguments: none
//
// return: whether or not this frame should display
//
// determine based on the frame number and class configuration if we
// should display data for this frame or not.
//
boolean DisplayData::shouldDisplayFrame() const {

  // ISIP_BUG #531: this needs to be overhauled
  //
  return true;
}
