
#include <string>
using namespace std;

#include <libsaria/tags.h>
#include <libsaria/library.h>
#include "library.h"

/*
 * Definitions for the LibraryPath class
 */
LibraryPath::LibraryPath(string dir)
{
	path = dir;
}

LibraryPath::LibraryPath(InFile &in, string dir)
{
	unsigned int size;
	ino_t inode;

	path = dir;
	size = in.read_lui();
	println("Library path dir: " + path);
	print("Library path size: ");
	println(size);

	for (unsigned int i = 0; i < size; i++) {
		inode = in.read_ino();
		file_map[inode] = TrackTag(in);
	}

}

LibraryPath::~LibraryPath()
{
}

void LibraryPath::insert_track(ino_t &inode, TrackTag &tag)
{
	file_map[inode] = tag;
}

void LibraryPath::update()
{
	ScanTask *task = new ScanTask(this, path, false);
	task->queue();
}

unsigned int LibraryPath::size()
{
	return file_map.size();
}


/*
 * Definitions for the ScanTask class
 */
ScanTask::ScanTask(LibraryPath *lib_path, string scan_dir, bool end)
{
	library = lib_path;
	dir     = scan_dir;
	end_dir = end;
}

ScanTask::~ScanTask()
{}

void ScanTask::tag_file(file filepath)
{
	try {
		TrackTag tag(dir + "/" + filepath.name);
		library->insert_track(filepath.d_ino, tag);
	} catch (string message) {
		println(message);
	}
}

/*
 * 1) Read a directory
 * 2) Find tags for each music file
 * 3) Create and queue a new ScanTask for each subdirectory
 */
void ScanTask::run_task()
{
	int last, i = 0;
	list<file> files;
	list<file> dirs;
	list<file>::iterator it;
	ScanTask *scan;
	SaveTask *save;

	readdir(dir, files, dirs);

	for (it = files.begin(); it != files.end(); it++)
		tag_file(*it);

	last = dirs.size() - 1;
	for (it = dirs.begin(); it != dirs.end(); it++) {
		scan = new ScanTask(library, dir + "/" + (*it).name, i == last);
		scan->queue();
		i++;
	}

	if (end_dir == true) {
		print("Library path size: ");
		println(library->size());
		save = new SaveTask(libsaria::library::save);
		save->queue_front();
		libsaria::library::refresh();
	}
}

namespace libsaria
{
	void library::add_path(string dir)
	{
		get_library_map()->insert(
				pair<string, LibraryPath>(dir, LibraryPath(dir))
		);
		update_path(dir);
	}

	void library::remove_path(string dir)
	{
		map<string, LibraryPath>::iterator it;
		it = get_library_map()->find(dir);
		if (it != get_library_map()->end()) {
			get_library_map()->erase(it);
			save();
			refresh();
		}
	}

	void library::update_path(string dir)
	{
		get_library_path(dir)->update();
	}
}; /* Namespace: libsaria */
