/*
 * GStreamer
 * Copyright (C) 2011 Robert Jobbagy <jobbagy.robert@gmail.com>
 * Copyright (C) 2011 Nicola Murino <nicola.murino@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Alternatively, the contents of this file may be used under the
 * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
 * which case the following provisions apply instead of the ones
 * mentioned above:
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/* This breaks the build for reasons that aren't entirely clear to me yet */
#if 0
//#ifdef HAVE_CONFIG_H
//#include "config.h"
//#endif
#endif

#include <stdio.h>
#include <limits.h>
#include "motioncells_wrapper.h"

static int instanceCounter = 0;
static bool element_id_was_max = false;

MotionCells *mc;
char p_str[] = "idx failed";

int
motion_cells_init ()
{
  mc = new MotionCells ();
  instanceOfMC tmpmc;
  tmpmc.id = instanceCounter;
  tmpmc.mc = mc;
  motioncellsvector.push_back (tmpmc);
  if ((instanceCounter < INT_MAX) && !element_id_was_max) {
    instanceCounter++;
    element_id_was_max = false;
  } else {
    element_id_was_max = true;
    instanceCounter = motioncellsfreeids.back ();
    motioncellsfreeids.pop_back ();
  }
  return tmpmc.id;
}

int
perform_detection_motion_cells (IplImage * p_image, double p_sensitivity,
    double p_framerate, int p_gridx, int p_gridy, long int p_timestamp_millisec,
    bool p_isVisible, bool p_useAlpha, int motionmaskcoord_count,
    motionmaskcoordrect * motionmaskcoords, int motionmaskcells_count,
    motioncellidx * motionmaskcellsidx, cellscolor motioncellscolor,
    int motioncells_count, motioncellidx * motioncellsidx, gint64 starttime,
    char *p_datafile, bool p_changed_datafile, int p_thickness, int p_id)
{
  int idx = 0;
  idx = searchIdx (p_id);
  return motioncellsvector.at (idx).mc->performDetectionMotionCells (p_image,
      p_sensitivity, p_framerate, p_gridx, p_gridy, p_timestamp_millisec,
      p_isVisible, p_useAlpha, motionmaskcoord_count, motionmaskcoords,
      motionmaskcells_count, motionmaskcellsidx, motioncellscolor,
      motioncells_count, motioncellsidx, starttime, p_datafile,
      p_changed_datafile, p_thickness);
}


void
setPrevFrame (IplImage * p_prevFrame, int p_id)
{
  int idx = 0;
  idx = searchIdx (p_id);
  motioncellsvector.at (idx).mc->setPrevFrame (p_prevFrame);
}

char *
getMotionCellsIdx (int p_id)
{
  int idx = 0;
  idx = searchIdx (p_id);
  if (idx > -1)
    return motioncellsvector.at (idx).mc->getMotionCellsIdx ();
  else {
    return p_str;
  }

}

int
getMotionCellsIdxCnt (int p_id)
{
  int idx = 0;
  idx = searchIdx (p_id);
  if (idx > -1)
    return motioncellsvector.at (idx).mc->getMotionCellsIdxCount ();
  else
    return 0;
}

bool
getChangedDataFile (int p_id)
{
  int idx = 0;
  idx = searchIdx (p_id);
  if (idx > -1)
    return motioncellsvector.at (idx).mc->getChangedDataFile ();
  else
    return false;
}

int
searchIdx (int p_id)
{
  for (unsigned int i = 0; i < motioncellsvector.size (); i++) {
    instanceOfMC tmpmc;
    tmpmc = motioncellsvector.at (i);
    if (tmpmc.id == p_id) {
      return i;
    }
  }
  return -1;
}

char *
getInitDataFileFailed (int p_id)
{
  int idx = 0;
  idx = searchIdx (p_id);
  if (idx > -1)
    return motioncellsvector.at (idx).mc->getDatafileInitFailed ();
  else {
    return p_str;
  }
}

char *
getSaveDataFileFailed (int p_id)
{
  int idx = 0;
  idx = searchIdx (p_id);
  if (idx > -1)
    return motioncellsvector.at (idx).mc->getDatafileSaveFailed ();
  else {
    return p_str;
  }
}

int
getInitErrorCode (int p_id)
{
  int idx = 0;
  idx = searchIdx (p_id);
  if (idx > -1)
    return motioncellsvector.at (idx).mc->getInitErrorCode ();
  else
    return -1;
}

int
getSaveErrorCode (int p_id)
{
  int idx = 0;
  idx = searchIdx (p_id);
  if (idx > -1)
    return motioncellsvector.at (idx).mc->getSaveErrorCode ();
  else
    return -1;
}

void
motion_cells_free (int p_id)
{
  int idx = 0;
  idx = searchIdx (p_id);
  if (idx > -1) {
    delete motioncellsvector.at (idx).mc;
    motioncellsvector.erase (motioncellsvector.begin () + idx);
    motioncellsfreeids.push_back (p_id);
  }
}

void
motion_cells_free_resources (int p_id)
{
  int idx = 0;
  idx = searchIdx (p_id);
  if (idx > -1)
    motioncellsvector.at (idx).mc->freeDataFile ();
}
