// ---------------------------------------------------------------------------
// - QuarkArray.cpp                                                          -
// - standard object library - quark dynamic array class implementation      -
// ---------------------------------------------------------------------------
// - This program is free software;  you can redistribute it  and/or  modify -
// - it provided that this copyright notice is kept intact.                  -
// -                                                                         -
// - This program  is  distributed in  the hope  that it will be useful, but -
// - without  any  warranty;  without  even   the   implied    warranty   of -
// - merchantability or fitness for a particular purpose.  In no event shall -
// - the copyright holder be liable for any  direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software.     -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2019 amaury darsch                                   -
// ---------------------------------------------------------------------------

#include "Exception.hpp"
#include "QuarkArray.hpp"

namespace afnix {

  // -------------------------------------------------------------------------
  // - class section                                                         -
  // -------------------------------------------------------------------------

  // create an empty quark array

  QuarkArray::QuarkArray (void) {
    d_size   = 0;
    d_length = 0;
    p_array  = nullptr;
  }

  // create a quark array with an original size

  QuarkArray::QuarkArray (const long size) {
    if (size < 0) throw Exception ("size-error", "negative quark array size");
    d_size   = size;
    d_length = 0;
    p_array  = new long[d_size];
  }

  // copy constructor for this quark array

  QuarkArray::QuarkArray (const QuarkArray& that) {
    // copy arguments
    d_size   = that.d_length;
    d_length = that.d_length;
    p_array  = nullptr;    
    // create a new quark array of quarks and copy them
    if ((d_length > 0) && (that.p_array != nullptr)) {
      p_array = new long[d_length];
      for (long i = 0; i < d_length; i++)
	p_array[i] = that.p_array[i];
    }
  }
  
  // destroy this quark array
  
  QuarkArray::~QuarkArray (void) {
    delete [] p_array;
  }

  // reset this quark array

  void QuarkArray::reset (void) {
    delete [] p_array;
    d_size   = 0;
    d_length = 0;
    p_array  = nullptr;
  }

  // return the number of elements

  long QuarkArray::length (void) const {
    return d_length;
  }

  // add a new element in this quark array
  
  void QuarkArray::add (const long quark) {
    // check if we have to resize the quark array
    if (d_length + 1 >= d_size) {
      long  size  = (d_size <= 0) ? 1 : d_size * 2;
      long* array = new long[size];
      for (long i = 0; i < d_length; i++) array[i] = p_array[i];
      delete [] p_array;
      d_size  = size;
      p_array = array;
    }
    p_array[d_length++] = quark;
  }

  // set a quark at a certain position

  void QuarkArray::set (const long index, const long quark) {
    // check that we are bounded
    if (index >= d_length) 
      throw Exception ("index-error","in quark array set");
    
    // set the object
    p_array[index] = quark;
  }
  
  // get a quark at a certain position

  long QuarkArray::get (const long index) const {
    // check that we are bounded
    if ((index < 0) || (index >= d_length)) {
      throw Exception ("index-error","in quark array set");
    }
    // get the object
    return p_array[index];
  }

  // check that a quark exists in this array

  bool QuarkArray::exists (const long quark) const {
    if (d_length == 0) return false;
    for (long i = 0; i < d_length; i++)
      if (p_array[i] == quark) return true;
    return false;
  }
  
  // return the index of a quark or -1

  long QuarkArray::find (const long quark) const {
    for (long i = 0; i < d_length; i++) {
      if (p_array[i] == quark) return i;
    }
    return -1;
  }

  // return the index of a quark in this quark array

  long QuarkArray::lookup (const long quark) const {
    for (long i = 0; i < d_length; i++) {
      if (p_array[i] == quark) return i;
    }
    throw Exception ("quark-error","quark not found with mapping",
		     String::qmap (quark));
  }
}
