/*
 * 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);
  if (idx > -1)
    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);
  else
    return -1;
}


void
setPrevFrame (IplImage * p_prevFrame, int p_id)
{
  int idx = 0;
  idx = searchIdx (p_id);
  if (idx > -1)
    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 ();
}
