// file: sig_write_0.cc
//

// system include files
//
#include <string.h>

// isip include files
//
#include "Signal.h"
#include "signal_constants.h"

// method: write_cc
//
// arguments
//   float_8* data: (input) portion of the signal to output. this memory
//                  is allocated internally. pointer must be null on entry
//   float_8 start_time: (input) beginning point of the desired data
//   int_4 num_samples: (input) number of samples to write
//
// return: logical_1 indicating status
//
// this method writes the desired time window.
//
logical_1 Signal::write_cc(float_8* data_a, float_8 start_time_a,
			   int_4 num_samples_a) {

  // make sure that the file is open
  //
  if (fp_d == (FILE*)NULL) {

    // return with error
    //
    error_handler_cc((char_1*)"write_cc", (char_1*)"signal file is not open");
    return ISIP_FALSE;
  }

  // make sure that the data pointer is null, else error
  //
  if (data_a == (float_8*)NULL) {

    // return with error
    //
    error_handler_cc((char_1*)"write_cc", (char_1*)"data is not allocated");
    return ISIP_FALSE;
  }

  // rewind the input file
  //
  rewind(fp_d);

  // test the bounds of the start time
  //
  if (start_time_a > end_file_time_d) {

    // return with error
    //
    error_handler_cc((char_1*)"write_cc", (char_1*)"start time too large");
    return ISIP_FALSE;
  }

  // test the bounds of the start time
  //
  if (start_time_a < (float_8)0.0) {

    // set start time to 0.0
    //
    start_time_a = 0.0;
  }

  // allocate memory for the output data
  //
  char_1* out_data = new char_1[num_samples_a * num_chans_d * num_bytes_d];

  // loop over the input data and convert it to the proper output type
  //
  int_4 loop_its = num_samples_a * num_chans_d;
  for (int_4 i = 0; i < loop_its; i++) {

    // compute the sample value
    //
    if (num_bytes_d == (int_4)2) {
      ((short*)(out_data))[i] = (short)data_a[i];
    }
    else if (num_bytes_d == (int_4)4) {
      ((int_4*)(out_data))[i] = (int_4)data_a[i];
    }
    else {

      // free memory
      //
      delete [] out_data;

      // return with error
      //
      error_handler_cc((char_1*)"write_cc",
		       (char_1*)"number of bytes per sample is invalid");
      return ISIP_FALSE;
    }
  }
  
  // swap bytes if necessary
  //
  if (swap_byte_flag_d == ISIP_TRUE) {
    
    // loop over all two-byte sequences and swap bytes
    //
    // determine how many times through the loop we should go
    //
    int_4 loop_its = (num_samples_a * num_bytes_d * num_chans_d) / (int_4)2;

    // set a pointer to the beginning of the buffer
    //
    char_1* temp = out_data;
    for (int_4 i = 0; i < loop_its; i++) {
      char_1 samp = temp[0];
      temp[0] = temp[1];
      temp[1] = samp;
      temp += 2;
    }
  }

  // seek to the starting point in the file
  //
  fseek(fp_d, (int_4)(start_time_a * sf_d) * num_bytes_d * num_chans_d,
	SEEK_SET);

  // write the data out to file
  //
  int_4 samples_writ = fwrite(out_data, num_chans_d * num_bytes_d,
			     num_samples_a, fp_d);

  // check that the number of samples written is correct
  //
  if (samples_writ != num_samples_a) {

    // return with error
    //
    error_handler_cc((char_1*)"write_cc",
		     (char_1*)"could not read all samples");
    return ISIP_FALSE;
  }

  // determine the new size of the file
  //
  rewind(fp_d);
  fseek(fp_d, 0, SEEK_END);
  file_size_d = ftell(fp_d);
  end_file_time_d = (float_8)file_size_d / (sf_d * (float_8)num_bytes_d *
					    (float_8)num_chans_d);
  
  // delete memory and clean up
  //
  delete [] out_data;
  
  // exit gracefully
  //
  return ISIP_TRUE;
}



