/** \file arrayfs.cpp .
-----------------------------------------------------------------------------


 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.

-----------------------------------------------------------------------------

   Description:

-----------------------------------------------------------------------------


-------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------- */
/*       Include dependencies                                              */
/* ----------------------------------------------------------------------- */
#include "uima/arrayfs.hpp"
#include "uima/featurestructure.hpp"
#include "uima/lowlevel_fsheap.hpp"
#include "uima/msg.h"
#include "uima/internal_fspromoter.hpp"
#include "uima/internal_typeshortcuts.hpp"
#include "uima/internal_fsvalue_accessors.hpp"

/* ----------------------------------------------------------------------- */
/*       Constants                                                         */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Forward declarations                                              */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Implementation                                                    */
/* ----------------------------------------------------------------------- */
namespace uima {

  /* ----------------------------------------------------------------------- */
  /*       Exceptions Implementation                                         */
  /* ----------------------------------------------------------------------- */

  UIMA_EXC_CLASSIMPLEMENT(FSIsNotArrayException, CASException);
  UIMA_EXC_CLASSIMPLEMENT(FSArrayOutOfBoundsException, CASException);

  /* ----------------------------------------------------------------------- */
  /*       Tool Functions Implementation                                     */
  /* ----------------------------------------------------------------------- */

  void checkArray(const uima::lowlevel::TyFSType ARRAY_TYPE, lowlevel::TyFS tyFS, uima::lowlevel::FSHeap * pFSSystem, TyMessageId tyContext) {
    assert(EXISTS(pFSSystem));
    if (pFSSystem->getType( tyFS) != ARRAY_TYPE ) {
      UIMA_EXC_THROW_NEW(FSIsNotArrayException,
                         UIMA_ERR_FS_IS_NOT_ARRAY,
                         UIMA_MSG_ID_EXC_FS_IS_NOT_ARRAY,
                         ErrorMessage(tyContext),
                         ErrorInfo::recoverable
                        );
    }
  }

  void checkArraySize(lowlevel::TyFS tyFS, uima::lowlevel::FSHeap * pFSSystem, size_t n, TyMessageId tyContext) {
    size_t uiSize = pFSSystem->getArraySize(tyFS);
    if (n >= uiSize) {
      ErrorMessage err(UIMA_MSG_ID_EXC_ARRAY_OUT_OF_BOUNDS);
      err.addParam(n);
      err.addParam(uiSize);
      UIMA_EXC_THROW_NEW(FSArrayOutOfBoundsException,
                         UIMA_ERR_FS_ARRAY_OUT_OF_BOUNDS,
                         err,
                         ErrorMessage(tyContext),
                         ErrorInfo::recoverable
                        );
    }
  }

  /* ----------------------------------------------------------------------- */
  /*       BasicArrayFS                                                      */
  /* ----------------------------------------------------------------------- */
  template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
  BasicArrayFS<T, ARRAY_TYPE>::BasicArrayFS(lowlevel::TyFS anFS, uima::CAS & rFSSystem, bool bDoChecks) :
      FeatureStructure(anFS, rFSSystem) {
    if (bDoChecks) {
      checkValidity(UIMA_MSG_ID_EXCON_CREATING_ARRAYFS);
      checkArray(ARRAY_TYPE, iv_tyFS, iv_cas->getHeap(), UIMA_MSG_ID_EXCON_CREATING_ARRAYFS);
    }
  }

  template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
  BasicArrayFS<T, ARRAY_TYPE>::BasicArrayFS() :
      FeatureStructure() {}

  template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
  BasicArrayFS<T, ARRAY_TYPE>::BasicArrayFS( FeatureStructure const & fs) :
      FeatureStructure(fs) {
    // don't do checks here, exceptions should only be thrown
    // when accessing an invalid object
    if (isValid()) {
      checkArray(ARRAY_TYPE, iv_tyFS, iv_cas->getHeap(), UIMA_MSG_ID_EXCON_CREATING_ARRAYFS);
    }
    // we should not have any additional members
    assert(sizeof(BasicArrayFS) == sizeof(FeatureStructure));
  }

  template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
  T BasicArrayFS<T, ARRAY_TYPE>::get(size_t n) const {
      checkValidity(UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
      checkArraySize(iv_tyFS, iv_cas->getHeap(), n, UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
      uima::lowlevel::TyFSType typecode = iv_cas->getHeap()->getType(iv_tyFS);
      T result;
      if (typecode == uima::internal::gs_tyIntArrayType ||
          typecode == uima::internal::gs_tyFloatArrayType  ||
          typecode == uima::internal::gs_tyStringArrayType ||
          typecode == uima::internal::gs_tyFSArrayType) {
        lowlevel::TyHeapCell* pArray = iv_cas->getHeap()->getCArrayFromFS(iv_tyFS);
        uima::internal::fromHeapCellTempl(pArray[n], *iv_cas, result );
      } else {
        size_t pos = iv_cas->getHeap()->getArrayOffset(iv_tyFS) + n;
        uima::internal::fromHeapCellTempl(pos, *iv_cas, result );
      }
      return result;
    }

  template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
  void BasicArrayFS<T, ARRAY_TYPE>::set(size_t n, T const & val) {
    checkValidity(UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
    checkArraySize(iv_tyFS, iv_cas->getHeap(), n, UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
    uima::lowlevel::TyFSType typecode = iv_cas->getHeap()->getType(iv_tyFS);
    if (typecode == uima::internal::gs_tyIntArrayType ||
        typecode == uima::internal::gs_tyFloatArrayType  ||
        typecode == uima::internal::gs_tyStringArrayType ||
        typecode == uima::internal::gs_tyFSArrayType) {
      lowlevel::TyHeapCell* pArray = iv_cas->getHeap()->getCArrayFromFS(iv_tyFS);
      uima::lowlevel::TyHeapCell result = uima::internal::toHeapCellTempl(val, *iv_cas->getHeap(),0);
      pArray[n] = result;
    } else {
      size_t pos = iv_cas->getHeap()->getArrayOffset(iv_tyFS) + n;
      uima::lowlevel::TyHeapCell result = uima::internal::toHeapCellTempl(val, *iv_cas->getHeap(),pos);
    }

  }

  template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
  size_t BasicArrayFS<T, ARRAY_TYPE>::size() const {
    checkValidity(UIMA_MSG_ID_EXCON_GETTING_ARRAYSIZE_FROM_FS);
    return iv_cas->getHeap()->getArraySize(iv_tyFS);
  }

  template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
  void BasicArrayFS<T, ARRAY_TYPE>::copyToArray(
    size_t uiStart,
    size_t uiEnd,
    T* destArray,
    size_t uiDestOffset) const {
      checkValidity(UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
      checkArraySize(iv_tyFS, iv_cas->getHeap(), uiEnd - uiStart , UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
      uima::lowlevel::TyFSType typecode = iv_cas->getHeap()->getType(iv_tyFS);
      T result;
	  size_t srcOffset = uiStart;
	  size_t numelements = uiEnd-uiStart+1;
	  size_t destOffset = uiDestOffset;

	  if (typecode== uima::internal::gs_tyIntArrayType || 
		  typecode== uima::internal::gs_tyFloatArrayType   ) {
			  iv_cas->getHeap()->copyToArray( srcOffset,iv_tyFS,(uima::lowlevel::TyHeapCell*) destArray,destOffset,numelements);
	  } else if(typecode== uima::internal::gs_tyByteArrayType || 
		        typecode== uima::internal::gs_tyBooleanArrayType) {
		  iv_cas->getHeap()->copyToArray( srcOffset,iv_tyFS,(char*) destArray,destOffset,numelements);
	  } else if(typecode== uima::internal::gs_tyShortArrayType ) {
		  iv_cas->getHeap()->copyToArray( srcOffset,iv_tyFS,(short*) destArray,destOffset,numelements);
      } else if(typecode== uima::internal::gs_tyLongArrayType || 
		        typecode== uima::internal::gs_tyDoubleArrayType) {
		  iv_cas->getHeap()->copyToArray( srcOffset,iv_tyFS,(INT64*) destArray,destOffset,numelements);
      } else {
      assertWithMsg(false, "Not yet implemented");
      UIMA_EXC_THROW_NEW(NotYetImplementedException,
                 UIMA_ERR_NOT_YET_IMPLEMENTED,
                 UIMA_MSG_ID_EXC_NOT_YET_IMPLEMENTED,
                 ErrorMessage(UIMA_MSG_ID_EXCON_UNKNOWN_CONTEXT),
                 ErrorInfo::unrecoverable
                );
      }
  }
  template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
  void BasicArrayFS<T, ARRAY_TYPE>::copyFromArray(
  T const * sourceArray,
    size_t uiStart,
    size_t uiEnd,
    size_t uiOffset) {
      checkValidity(UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
      checkArraySize(iv_tyFS, iv_cas->getHeap(), uiEnd - uiStart, UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
      
	  size_t srcOffset = uiStart;
	  size_t numelements = uiEnd-uiStart+1;
	  size_t destOffset = uiOffset;
	  checkArraySize(iv_tyFS, iv_cas->getHeap(), destOffset+numelements-1, UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
      uima::lowlevel::TyFSType typecode = iv_cas->getHeap()->getType(iv_tyFS);

	  if (typecode== uima::internal::gs_tyIntArrayType || 
		  typecode== uima::internal::gs_tyFloatArrayType   ) {
	    iv_cas->getHeap()->copyFromArray(  (uima::lowlevel::TyHeapCell *) sourceArray, srcOffset,  iv_tyFS, destOffset, numelements);
      }
      else if(typecode== uima::internal::gs_tyByteArrayType || 
		  typecode== uima::internal::gs_tyBooleanArrayType ) {
		iv_cas->getHeap()->copyFromArray(  (char *) sourceArray, srcOffset,  iv_tyFS, destOffset, numelements);
       
      }
	  else if(typecode== uima::internal::gs_tyShortArrayType) {
       	iv_cas->getHeap()->copyFromArray(  (short *) sourceArray, srcOffset,  iv_tyFS, destOffset, numelements);
      }
	  else if(typecode== uima::internal::gs_tyLongArrayType ||
		  typecode == uima::internal::gs_tyDoubleArrayType ) {
       	iv_cas->getHeap()->copyFromArray(  (INT64 *) sourceArray, srcOffset,  iv_tyFS, destOffset, numelements);
      }
      else {
        assertWithMsg(false, "Not yet implemented");
        UIMA_EXC_THROW_NEW(NotYetImplementedException,
                         UIMA_ERR_NOT_YET_IMPLEMENTED,
                         UIMA_MSG_ID_EXC_NOT_YET_IMPLEMENTED,
                         ErrorMessage(UIMA_MSG_ID_EXCON_UNKNOWN_CONTEXT),
                         ErrorInfo::unrecoverable
                        );

    }
  }

  template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
  /*static*/ BasicArrayFS<T, ARRAY_TYPE> BasicArrayFS<T, ARRAY_TYPE>::createArrayFS( CAS & cas, size_t uiSize, bool bIsPermanent) {
    assertWithMsg( sizeof(FeatureStructure::TyArrayElement) == sizeof(lowlevel::TyHeapCell), "Port required");
    uima::lowlevel::FSHeap & heap =  *uima::internal::FSPromoter::getFSHeap(cas);
    lowlevel::TyFS tyFS = heap.createArrayFS(ARRAY_TYPE, uiSize);
    return BasicArrayFS(internal::FSPromoter::promoteFS( tyFS, cas ));
  }

  // explicit instantiation
  template class BasicArrayFS< FeatureStructure, internal::gs_tyFSArrayType >;
  // explicit instantiation
  template class BasicArrayFS< float, internal::gs_tyFloatArrayType >;
  // explicit instantiation
  template class BasicArrayFS< int, internal::gs_tyIntArrayType >;
  // explicit instantiation
  template class BasicArrayFS< UnicodeStringRef, internal::gs_tyStringArrayType >;


  // explicit instantiation
  template class BasicArrayFS< bool, internal::gs_tyBooleanArrayType >;
  template class BasicArrayFS< char, internal::gs_tyByteArrayType >;
  template class BasicArrayFS< short, internal::gs_tyShortArrayType >;
  template class BasicArrayFS< INT64, internal::gs_tyLongArrayType >;
  template class BasicArrayFS< double, internal::gs_tyDoubleArrayType >;



} // namespace uima

/* ----------------------------------------------------------------------- */
/* <EOF> */

