/* timestamp.c generated by valac 0.26.1, the Vala compiler
 * generated from timestamp.vala, do not modify */

/* timestamp.vala
 *
 * Copyright © 2012 Collabora Ltd.
 *             By Siegfried-Angel Gevatter Pujals <siegfried@gevatter.com>
 * Copyright © 2010 Canonical, Ltd.
 *             By Mikkel Kamstrup Erlandsen <mikkel.kamstrup@canonical.com>
 *
 * This program 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 program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>




#define ZEITGEIST_TIMESTAMP_SECOND ((gint64) 1000)
#define ZEITGEIST_TIMESTAMP_MINUTE ((gint64) 60000)
#define ZEITGEIST_TIMESTAMP_HOUR ((gint64) 3600000)
#define ZEITGEIST_TIMESTAMP_DAY ((gint64) 86400000)
#define ZEITGEIST_TIMESTAMP_WEEK ((gint64) 604800000)
#define ZEITGEIST_TIMESTAMP_YEAR 31556952000LL
gint64 zeitgeist_timestamp_from_timeval (GTimeVal* timeval);
void zeitgeist_timestamp_to_timeval (gint64 timestamp, GTimeVal* result);
gint64 zeitgeist_timestamp_from_now (void);
gint64 zeitgeist_timestamp_from_iso8601 (const gchar* datetime);
gchar* zeitgeist_timestamp_to_iso8601 (gint64 timestamp);
gint64 zeitgeist_timestamp_from_date (GDate* date);
gint64 zeitgeist_timestamp_prev_midnight (gint64 timestamp);
gint64 zeitgeist_timestamp_from_dmy (GDateDay day, GDateMonth month, GDateYear year);
void zeitgeist_timestamp_to_date (gint64 timestamp, GDate* result);
gint64 zeitgeist_timestamp_next_midnight (gint64 timestamp);


/**
     * Convert a {@link GLib.TimeVal} to an amount of milliseconds since
     * the Unix Epoch
     *
     * @param timeval time to convert
     *
     * @return number of milliseconds since the Unix Epoch
     */
gint64 zeitgeist_timestamp_from_timeval (GTimeVal* timeval) {
	gint64 result = 0LL;
	gint64 m_seconds = 0LL;
	GTimeVal _tmp0_ = {0};
	glong _tmp1_ = 0L;
	GTimeVal _tmp2_ = {0};
	glong _tmp3_ = 0L;
	g_return_val_if_fail (timeval != NULL, 0LL);
	_tmp0_ = *timeval;
	_tmp1_ = _tmp0_.tv_sec;
	m_seconds = ((gint64) _tmp1_) * 1000;
	_tmp2_ = *timeval;
	_tmp3_ = _tmp2_.tv_usec;
	result = m_seconds + (((gint64) _tmp3_) / 1000);
	return result;
}


/**
     * Write a Zeitgeist timestamp to a {@link GLib.TimeVal} instance.
     * Note that Zeitgeist uses only a millisecond resolution, whereas
     * {@link GLib.TimeVal} has microsecond resolution. This means that
     * the lower three digits of @tv.tv_usec will always be 0.
     *
     * @param timestamp to convert
     *
     * @return the equivalent {@link GLib.TimeVal} instance.
     */
void zeitgeist_timestamp_to_timeval (gint64 timestamp, GTimeVal* result) {
	GTimeVal timeval = {0};
	gint64 _tmp0_ = 0LL;
	gint64 _tmp1_ = 0LL;
	g_get_current_time (&timeval);
	_tmp0_ = timestamp;
	timeval.tv_sec = (glong) (_tmp0_ / 1000);
	_tmp1_ = timestamp;
	timeval.tv_usec = (glong) ((_tmp1_ % 1000) * 1000);
	*result = timeval;
	return;
}


/**
     * Return the current timestamp in milliseconds.
     *
     * @return the timestamp for the current system time, in milliseconds
     *         since the Unix Epoch
     */
gint64 zeitgeist_timestamp_from_now (void) {
	gint64 result = 0LL;
	gint64 _tmp0_ = 0LL;
	_tmp0_ = g_get_real_time ();
	result = _tmp0_ / 1000;
	return result;
}


/**
     * Parse a timestamp from an ISO8601-encoded string.
     *
     * @param datetime a string containing an ISO8601-conforming datetime
     *
     * @return the timestamp represented by the given string, or -1 if
     *         it can't be parsed
     */
gint64 zeitgeist_timestamp_from_iso8601 (const gchar* datetime) {
	gint64 result = 0LL;
	GTimeVal timeval = {0};
	const gchar* _tmp0_ = NULL;
	gboolean _tmp1_ = FALSE;
	g_return_val_if_fail (datetime != NULL, 0LL);
	g_get_current_time (&timeval);
	_tmp0_ = datetime;
	_tmp1_ = g_time_val_from_iso8601 (_tmp0_, &timeval);
	if (_tmp1_) {
		GTimeVal _tmp2_ = {0};
		gint64 _tmp3_ = 0LL;
		_tmp2_ = timeval;
		_tmp3_ = zeitgeist_timestamp_from_timeval (&_tmp2_);
		result = _tmp3_;
		return result;
	} else {
		result = (gint64) (-1);
		return result;
	}
}


/**
     * Convert a timestamp to a human-readable ISO8601 format
     *
     * @param timestamp a timestamp in milliseconds since the Unix Epoch
     *
     * @return a newly allocated string containing the ISO8601 version of
     *         the given timestamp
     */
gchar* zeitgeist_timestamp_to_iso8601 (gint64 timestamp) {
	gchar* result = NULL;
	GTimeVal timeval = {0};
	gint64 _tmp0_ = 0LL;
	GTimeVal _tmp1_ = {0};
	gchar* _tmp2_ = NULL;
	_tmp0_ = timestamp;
	zeitgeist_timestamp_to_timeval (_tmp0_, &_tmp1_);
	timeval = _tmp1_;
	_tmp2_ = g_time_val_to_iso8601 (&timeval);
	result = _tmp2_;
	return result;
}


/**
     * Convert a ''GDate'' to a Zeitgeist timestamp
     *
     * @param date the date to convert
     *
     * @return the given date expressed as a timestamp in milliseconds since
     *         the Epoch. The timestamp is guaranteed to be roudned off to the
     *         midnight of the given date.
     */
gint64 zeitgeist_timestamp_from_date (GDate* date) {
	gint64 result = 0LL;
	gint64 julian = 0LL;
	guint _tmp0_ = 0U;
	gint64 _tmp1_ = 0LL;
	g_return_val_if_fail (date != NULL, 0LL);
	_tmp0_ = g_date_get_julian (date);
	julian = (gint64) _tmp0_;
	_tmp1_ = zeitgeist_timestamp_prev_midnight ((julian * ZEITGEIST_TIMESTAMP_DAY) - (1969 * ZEITGEIST_TIMESTAMP_YEAR));
	result = _tmp1_;
	return result;
}


/**
     * Convert a day, month, year tuple into a Zeitgeist timestamp
     *
     * @param day the day of the month
     * @param month the month of the year
     * @param year the year
     *
     * @return the given date (rounded off to the midnight), expressed as
     *         a timestamp in milliseconds since the Epoch, or -1 in case
     *         the provided parameters don't constitute a valid date.
     */
gint64 zeitgeist_timestamp_from_dmy (GDateDay day, GDateMonth month, GDateYear year) {
	gint64 result = 0LL;
	GDate date = {0};
	GDateDay _tmp0_ = '\0';
	GDateMonth _tmp1_ = 0;
	GDateYear _tmp2_ = 0U;
	GDate _tmp3_ = {0};
	gint64 _tmp4_ = 0LL;
	memset (&date, 0, sizeof (GDate));
	_tmp0_ = day;
	_tmp1_ = month;
	_tmp2_ = year;
	g_date_set_dmy (&date, _tmp0_, (gint) _tmp1_, _tmp2_);
	_tmp3_ = date;
	_tmp4_ = zeitgeist_timestamp_from_date (&_tmp3_);
	result = _tmp4_;
	return result;
}


/**
     * Write a timestamp to a {@link GLib.Date} structure
     *
     * @param timestamp to convert
     * @return {@link GLib.Date} initialized to the given timestamp
     */
void zeitgeist_timestamp_to_date (gint64 timestamp, GDate* result) {
	GDate date = {0};
	GTimeVal timeval = {0};
	gint64 _tmp0_ = 0LL;
	GTimeVal _tmp1_ = {0};
	GTimeVal _tmp2_ = {0};
	memset (&date, 0, sizeof (GDate));
	_tmp0_ = timestamp;
	zeitgeist_timestamp_to_timeval (_tmp0_, &_tmp1_);
	timeval = _tmp1_;
	_tmp2_ = timeval;
	g_date_set_time_val (&date, &_tmp2_);
	*result = date;
	return;
}


/**
     * Calculate the timestamp for the next midnight after the given timestamp.
     *
     * If is is already midnight (down to the millisecond), this method will
     * return the value for the next midnight. In other words, you can call
     * this method recursively in order to iterate, forwards in time, over
     * midnights.
     *
     * @param timestamp the Zeitgeist timestamp to find the next midnight for
     *
     * @return the timestamp for the next midnight after the given timestamp
     */
gint64 zeitgeist_timestamp_next_midnight (gint64 timestamp) {
	gint64 result = 0LL;
	gint64 remainder = 0LL;
	gint64 _tmp0_ = 0LL;
	gint64 _tmp1_ = 0LL;
	_tmp0_ = timestamp;
	remainder = _tmp0_ % ZEITGEIST_TIMESTAMP_DAY;
	_tmp1_ = remainder;
	if (_tmp1_ == ((gint64) 0)) {
		gint64 _tmp2_ = 0LL;
		_tmp2_ = timestamp;
		result = _tmp2_ + ZEITGEIST_TIMESTAMP_DAY;
		return result;
	} else {
		gint64 _tmp3_ = 0LL;
		gint64 _tmp4_ = 0LL;
		_tmp3_ = timestamp;
		_tmp4_ = remainder;
		result = (_tmp3_ - _tmp4_) + ZEITGEIST_TIMESTAMP_DAY;
		return result;
	}
}


/**
     * Calculate the timestamp for the midnight just before the given
     * timestamp.
     *
     * If is is already midnight (down to the millisecond), this method will
     * return the value for the previous midnight. In other words, you can
     * call this method recursively in order to iterate, backwards in time,
     * over midnights.
     *
     * @param timestamp the Zeitgeist timestamp to find the previous
     *        midnight for
     *
     * @return the timestamp for the midnight just before the given timestamp
     */
gint64 zeitgeist_timestamp_prev_midnight (gint64 timestamp) {
	gint64 result = 0LL;
	gint64 remainder = 0LL;
	gint64 _tmp0_ = 0LL;
	gint64 _tmp1_ = 0LL;
	_tmp0_ = timestamp;
	remainder = _tmp0_ % ZEITGEIST_TIMESTAMP_DAY;
	_tmp1_ = remainder;
	if (_tmp1_ == ((gint64) 0)) {
		gint64 _tmp2_ = 0LL;
		_tmp2_ = timestamp;
		result = _tmp2_ - ZEITGEIST_TIMESTAMP_DAY;
		return result;
	} else {
		gint64 _tmp3_ = 0LL;
		gint64 _tmp4_ = 0LL;
		_tmp3_ = timestamp;
		_tmp4_ = remainder;
		result = _tmp3_ - _tmp4_;
		return result;
	}
}



