/*
    Copyright (C) 2008-2010 Stefan Haller

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 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 General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdlib.h>

#include "history.h"

#include "desktopnova-daemon.h"
#include "wallpapers.h"

#define MAX_TRY 10

guint history[HISTORY_MAX];
gint history_current;
gint history_size;

#ifdef DEBUG
void print_history()
{
	guint i;
	
	g_debug("print_history()");
	g_print("[ ");
	for (i = 0; i < history_size; i++)
	{
		if (i > 0)
		{
			g_print(", ");
		}
		g_print("%3u", history[i]);
	}
	g_print(" ]\n  ");
	for (i = history_current; i > 0; i--)
	{
		g_print("     ");
	}
	g_print("  ^\n");
	g_print("Current: %u\n", history_current);
	g_print("Size: %u\n", history_size);
}
#endif

void init_history()
{
	guint i;
	for (i = 0; i < HISTORY_MAX; i++)
	{
		history[i] = 0;
	}

	history_current = 0;
	history_size = 0;
}

void generate_new_wallpaper()
{
	guint new = rand() % wallpapers->len;
	if (wallpapers->len >= history_size)
	{
		for (;;)
		{
			guint i;
			gboolean exists = FALSE;
			for (i = 0; i < history_size; i++)
			{
				if (i == history_current)
				{
					continue;
				}
				
				if (history[i] == new)
				{
					exists = TRUE;
					break;
				}
			}

			if (! exists)
			{
				break;
			}

			new = rand() % wallpapers->len;
		}
	}
	history[history_current] = new;
}

void remove_from_history()
{
	guint i;
	for (i = history_current; i < HISTORY_MAX - 1; i++)
	{
		history[i] = history[i+1];
	}
	history_size--;

	if (history_current > history_size)
	{
		history_current = history_size - 1;
	}
}

void missing_wallpaper()
{
	#ifdef DEBUG
	g_debug("missing_wallpaper()");
	#endif

	guint index = history[history_current];
	g_ptr_array_remove_index(wallpapers, index);

	guint history_old = history_current;
	guint i;
	for (i = 0; i < history_size; i++)
	{
		if (history[i] == index)
		{
			history_current = i;
			remove_from_history();
			i--;
			if (history_old > i)
			{
				history_old--;
			}
		}
		else if (history[i] > index)
		{
			history[i]--;
		}
	}

	history_current = history_old;
}

gboolean next_wallpaper_()
{
	history_current++;
	if (history_current >= history_size)
	{
		if (history_size == HISTORY_MAX)
		{
			history_current = history_size - 1;
			guint i;
			for (i = 0; i < history_size - 1; i++)
			{
				history[i] = history[i+1];
			}
		}
		else
		{
			history_size++;
			history_current = history_size - 1;
		}
		generate_new_wallpaper();
	}

	if (! change_wallpaper(history[history_current]))
	{
		missing_wallpaper();
		history_current--;
		return FALSE;
	}

	return TRUE;
}

gboolean previous_wallpaper_()
{
	history_current--;
	if (history_current < 0)
	{
		guint i;
		for (i = HISTORY_MAX; i > 0; i--)
		{
			history[i] = history[i-1];
		}

		history_current = 0;
		generate_new_wallpaper();

		if (history_size != HISTORY_MAX)
			history_size++;
	}

	if (! change_wallpaper(history[history_current]))
	{
		missing_wallpaper();
		return FALSE;
	}

	return TRUE;
}

void next_wallpaper()
{
	guint i;
	for (i = 0; i < MAX_TRY; i++)
	{
		if (next_wallpaper_())
		{
			break;
		}
	}

	#ifdef DEBUG
	print_history();
	#endif
}

void previous_wallpaper()
{
	guint i;
	for (i = 0; i < MAX_TRY; i++)
	{
		if (previous_wallpaper_())
		{
			break;
		}
	}

	#ifdef DEBUG
	print_history();
	#endif
}
