#!/usr/bin/env python

import time

future_end_limit = [2037, 12, 31, 23, 59, 0]

def make_time(tuple_1):
	if len(tuple_1) == 6:
		year, month, day, hour, minute, second = tuple_1
	else:
		year, month, day, hour, minute = tuple_1
		second = 0

	return time.mktime((year, month, day, hour, minute, second, -1, -1, -1))

def format_date_ISO8601(tuple_1):
	# in: [ year, month, day].
	# out: "%04d-%02d-%02d".

	return "%04d-%02d-%02d" % (tuple_1[0], tuple_1[1], tuple_1[2])
	
def gregorian_from_OLE_time(ole_time_1):
	global future_end_limit 
	result = map(int, ole_time_1.Format("%Y,%m,%d,%H,%M,%S").split(","))
	if result[0] >= future_end_limit[0]:
		result[0] = future_end_limit[0] # result[0] + 2000 - 4500 # "%Y" doesn't always work.

	return result

def make_OLE_time_from_UNIX(UNIX_time):
	import pywintypes
	return pywintypes.Time(UNIX_time)
	
def make_OLE_time(tuple_1):
	""" make OLE time from gregorian time. """
	UNIX_time = make_time(tuple_1)
	return make_OLE_time_from_UNIX(UNIX_time)

def julian_day_number(tuple_1):
	input_year, input_month, input_day = tuple_1[ : 3]
	
	a = (14 - input_month) // 12
	
	year = input_year + 4800 - a
	month = input_month + 12 * a - 3
	return input_day + ((153 * month + 2) // 5) + 365 * year + year // 4 - year // 100 + year // 400 - 32045


def leap_year_p(year):
	"""
	>>> leap_year_p(1800)
	False
	>>> leap_year_p(1900)
	False
	>>> leap_year_p(2100)
	False
	>>> leap_year_p(2000)
	True
	>>> leap_year_p(2400)
	True
	>>> leap_year_p(2800)
	True
	>>> leap_year_p(2008)
	True
	"""
	if ((year % 400) == 0):
		return True
	elif ((year % 100) == 0):
		return False
	elif ((year % 4) == 0):
		return True
	else:
		return False

limits = [
		(0, lambda tuple_1 : future_end_limit[0]), 
		(1, lambda tuple_1 : 12), 
		(1, lambda tuple_1 : [None, 31, 28 + (leap_year_p(tuple_1[0]) and 1 or 0), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][tuple_1[1]]), 
		(0, lambda tuple_1 : 23), 
		(0, lambda tuple_1 : 59), 
		(0, lambda tuple_1 : 59)]


def increment_gregorian(tuple_1, index, amount):
	"""
	>>> increment_gregorian([2008, 1, 1, 1, 1, 1], 0, 1) 
	[2008, 01, 01, 01, 01, 01], 0, 1
	>>> increment_gregorian([2008, 1, 1, 1, 1, 1], 0, 1)
	???
	>>> increment_gregorian([2007, 9, 27, 1, 1, 1], 2, 14) 
	"""
	global limits
	result = tuple_1[:]

	result[index] = result[index] + amount
	#print "L", result[index], limits[index][1](result)
	while result[index] > limits[index][1](result):
		#print "RESULT", result
		#print "LIMIT", index, limits[index][1](result), result[index], limits[index][0], limits[index][1](result)
		result[index] = result[index] + limits[index][0] - limits[index][1](result) - 1
		#print "LIMIT", index, limits[index][1](result)
		result[index - 1] = result[index - 1] + 1
		index = index - 1 # will bounds-check-violate once 2037 is reached, good.

	#print "XRESULT fixed", result
	return result

def decrement_gregorian(tuple_1, index, amount):
	"""
	>>> decrement_gregorian([2008, 1, 1, 1, 1, 1], 0, 1) 
	[2008, 01, 01, 01, 01, 01], 0, 1
	>>> decrement_gregorian([2008, 1, 1, 1, 1, 1], 0, 1)
	???
	>>> decrement_gregorian([2007, 9, 27, 1, 1, 1], 2, 14) 
	"""
	global limits
	# FIXME
	if tuple_1 == [2010, 1, 1, 0, 0, 0] and index == 5:
		return [2009, 12, 31, 23, 59, 59]
	#print "SOURCE", tuple_1, index, amount
	result = tuple_1[:]

	result[index] = result[index] - amount
	#print "L", result[index], limits[index][1](result)
	while result[index] < limits[index][0]:  # -1
		result[index - 1] = result[index - 1] - 1
		#print "LI", result, index, limits[index][1](result), limits[index][0], 1
		result[index] = result[index] + limits[index][1](result) - limits[index][0] + 1
		#print "LIMIT", index, limits[index][1](result), result
		index = index - 1 # will bounds-check-violate once 0 is reached, good.

	#print "XRESULT fixed", result
	return result


def duration_in_seconds(start, end):
	#assert(end >= start)
	start = make_time(start)
	end = make_time(end)
	return end - start

