package com.tibbo.aggregate.common.expression.function.datablock;

import java.text.MessageFormat;

import com.tibbo.aggregate.common.Cres;
import com.tibbo.aggregate.common.data.Data;
import com.tibbo.aggregate.common.expression.EvaluationEnvironment;
import com.tibbo.aggregate.common.expression.EvaluationException;
import com.tibbo.aggregate.common.expression.Evaluator;
import com.tibbo.aggregate.common.expression.Function;
import com.tibbo.aggregate.common.expression.function.AbstractFunction;

public class CopyBytesFunction extends AbstractFunction
{
  public CopyBytesFunction()
  {
    super("copyBytes", Function.GROUP_DATA_BLOCK_PROCESSING, "DataBlock source, Integer sourceIndex, DataBlock target, Integer targetIndex, Integer length", "DataBlock",
        Cres.get().getString("fDescCopyBytes"));
    
  }
  
  @Override
  public Object execute(Evaluator evaluator, EvaluationEnvironment environment, Object... parameters) throws EvaluationException
  {
    checkParameters(5, false, parameters);
    Data source = (Data) parameters[0];
    int sourceIndex = ((Number) parameters[1]).intValue();
    Data target = (Data) parameters[2];
    int targetIndex = ((Number) parameters[3]).intValue();
    int length = ((Number) parameters[4]).intValue();

    if (sourceIndex >= source.getData().length || sourceIndex < 0)
    {
      throw new EvaluationException(MessageFormat.format(Cres.get().getString("fErrOutOfBound"), sourceIndex));
    }
    
    if (targetIndex >= target.getData().length || targetIndex < 0)
    {
      throw new EvaluationException(MessageFormat.format(Cres.get().getString("fErrOutOfBound"), targetIndex));
    }
    
    if (length < 0 || sourceIndex + length >= source.getData().length || targetIndex + length >= target.getData().length)
    {
      throw new EvaluationException(MessageFormat.format(Cres.get().getString("fErrLength"), length));
    }
    
    System.arraycopy(source.getData(), sourceIndex, target.getData(), targetIndex, length);
    
    return target;
  }
}
