/*!
 * Event.cpp
 *
 * Copyright (c) 2016-2018, NADAL Jean-Baptiste. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA
 * 
 * @Author:  NADAL Jean-Baptiste
 * @Date: 19/05/2016
 *
 */


/*------------------------------- INCLUDES ----------------------------------*/

#include "devices/devices-manager.h"

#include "timers/event.h"

/*!  ----------------------------------------------------------------------------
 *  @fn Event
 *
 *  @brief Constructor of Timer Event Object.
 */
Event::Event (void):

	mActive(false),
	mID(0),
	mDeviceID(0),
	mHour(0),
	mMinute(0),
	mRecurrence(0),
	mDuration(0),
	mInProgress (false)
{
}


/*!  ----------------------------------------------------------------------------
 *  @fn ~Event
 *
 *  @brief Destructor of Timer Event Object.
 */
Event::~Event (void)
{
}


/*!  ----------------------------------------------------------------------------
 *  @fn load_from_json
 *
 *  @brief Load Event Object.
 */
int Event::load_from_json (Json::Value anElem)
{
	std::size_t theSeparator;
	std::string::size_type sz;   // alias of size_t

	mID = anElem["id"].asInt();

	mActive = anElem["active"].asBool();

	std::string theIDElem = anElem["id"].asString();
	theSeparator = theIDElem.find_last_of("/");
	
	mCapability = theIDElem.substr(0, theSeparator);
	mDeviceID = std::stoi (theIDElem.substr (theSeparator + 1), &sz);

	std::string theStarTime = anElem["start_time"].asString();
	theSeparator = theStarTime.find_last_of(":");

	mHour = std::stoi (theStarTime.substr (0, theSeparator), &sz);
	mMinute =  std::stoi (theStarTime.substr (theSeparator + 1), &sz);

	mRecurrence = anElem["recurrence"].asInt();
	mDuration = anElem["duration"].asInt();

	mAction = anElem["action"].asString();

	return 0;
}


/*!  ----------------------------------------------------------------------------
 *  @fn to_json
 *
 *  @brief Export Event Object as JSON Object.
 */
Json::Value Event::to_json (void) const
{
	Json::Value aResult(Json::objectValue);

	aResult ["id"] = mID;

	aResult ["active"] = mActive;
	aResult ["device_id"] = mCapability + "/" + std::to_string(mDeviceID);
	aResult ["action"] = mAction;

	aResult["recurrence"] = mRecurrence;
	aResult["duration"] = mDuration;

	aResult["start_time"] = std::to_string(mHour) + ":" + std::to_string(mMinute);

	return aResult;
}


/*!  ----------------------------------------------------------------------------
 *  @fn start
 *
 *  @brief Stop the Event.
 */
int Event::start (Devices *aDevices)
{
	setInProgress (true);

	return aDevices->set (mCapability.c_str(), mDeviceID, true);
}


/*!  ----------------------------------------------------------------------------
 *  @fn stop
 *
 *  @brief Stop the Event.
 */
int Event::stop (Devices *aDevices)
{
	setInProgress (false);

	return aDevices->set (mCapability.c_str(), mDeviceID, false);
}


/*!  ----------------------------------------------------------------------------
 *  @fn dump
 *
 *  @brief dump the Event Object.
 */
void Event::dump (void)
{
	fprintf (stdout, "Timer Event:\n");
	fprintf (stdout, "=========== \n");
	fprintf (stdout, "  - active: %s\n", (mActive?"true":"false"));
	fprintf (stdout, "  - capability: %s\n", mCapability.c_str());
	fprintf (stdout, "  - id: %d\n", mID);
	fprintf (stdout, "  - device_id: %d\n", mDeviceID);
	fprintf (stdout, "  - Time: %2d:%2d\n", mHour, mMinute);
	fprintf (stdout, "  - recurrence: %d\n", mRecurrence);
	fprintf (stdout, "  - duration: %d\n", mDuration);
	fprintf (stdout, "  - action: %s\n", mAction.c_str());
}


/*!  ----------------------------------------------------------------------------
 *  @fn isActive
 *
 *  @brief return true if the Timer event is active.
 */
bool Event::isActive (void) const
{
	return mActive;
}


/*!  ----------------------------------------------------------------------------
 *  @fn getCapability
 *
 *  @brief return the capability of the Event.
 */
std::string Event::getCapability (void) const
{
	return mCapability;
}


/*!  ----------------------------------------------------------------------------
 *  @fn getID
 *
 *  @brief return the ID of the Event.
 */
uint16_t Event::getID (void) const
{
	return mID;
}


/*!  ----------------------------------------------------------------------------
 *  @fn getDeviceID
 *
 *  @brief return the Device ID of the Event.
 */
uint16_t Event::getDeviceID (void) const
{
	return mDeviceID;
}


/*!  ----------------------------------------------------------------------------
 *  @fn getHour
 *
 *  @brief Return the Hour of the Event.
 */
uint8_t Event::getHour (void) const
{
	return mHour;
}


/*!  ----------------------------------------------------------------------------
 *  @fn getMinute
 *
 *  @brief Return the Minute of the Event.
 */
uint8_t Event::getMinute (void) const
{
	return mMinute;
}


/*!  ----------------------------------------------------------------------------
 *  @fn getRecurrence
 *
 *  @brief Return the Recurrency of the Event.
 */
uint16_t Event::getRecurrence (void) const
{
	return mRecurrence;
}


/*!  ----------------------------------------------------------------------------
 *  @fn getDuration
 *
 *  @brief Return the Duration of the Event.
 */
uint16_t Event::getDuration (void) const
{
	return mDuration;
}


/*!  ----------------------------------------------------------------------------
 *  @fn getAction
 *
 *  @brief Return the Action of the Event.
 */
std::string Event::getAction (void) const
{
	return mAction;
}


/*!  ----------------------------------------------------------------------------
 *  @fn isInProgress
 *
 *  @brief Return true if the Event Is in Progress.
 */
bool Event::isInProgress (void) const
{
	return mInProgress;
}


/*!  ----------------------------------------------------------------------------
 *  @fn setInProgress
 *
 *  @brief Set the InProgress to a new state.
 */
void Event::setInProgress (bool aState)
{
	mInProgress = aState;
}
