#ifdef __STRICT_ANSI__
#undef __STRICT_ANSI__
#endif

#include <windows.h>
#include <dirent.h>
#include <vlc/vlc.h>
#include <strings.h>

#include "level.h"
#include "exception.h"

const char *MediaInfo::m_image_types[] = { "jpg", "gif", "png" };
const char *MediaInfo::m_video_types[] = { "3gp", "asf", "avi", "flv", "mkv", "mov", "ogm", "vob", "mp4", "mpv" };

MediaInfo::MediaInfo(libvlc_instance_t *instance, const char *pathname) : m_media_type(MT_NONE), m_path_name(pathname) {
	const char *p = strrchr(pathname, '.');
	if ( p ){
		p++;
		unsigned int ii;
		for ( ii=0 ; ii<sizeof(m_image_types)/sizeof(const char *) ; ii++ ){
			if ( stricmp(p, m_image_types[ii])==0 ){
				m_media_type = MT_IMAGE;
				break;
				}
			}
		if ( m_media_type==MT_NONE ){
			for ( ii=0 ; ii<sizeof(m_video_types)/sizeof(const char *) ; ii++ ){
				if ( stricmp(p, m_video_types[ii])==0 ){
					m_media_type = MT_VIDEO;
					break;
					}
				}
			}
		if ( m_media_type==MT_VIDEO || m_media_type==MT_IMAGE ){
			m_vlc_media = libvlc_media_new_path(instance, pathname);
			if ( !m_vlc_media )
				throw new PammmException("Failed to create VLC media", pathname);
			}
		}
	else throw new PammmException("Invalid file name", pathname);
}

MediaInfo::~MediaInfo() { }


Level::Level(libvlc_instance_t *instance, const std::string &root_path, const char dircode) : m_instance(instance), m_index(0) {

	// Compile complete path.

	unsigned int fsize = root_path.size()+4;
	char *buf = new char[fsize];
	strcpy(buf, root_path.c_str());
	fsize -= 4;
	if ( buf[fsize-1]!='\\' )
		buf[fsize++] = '\\';
	buf[fsize++] = dircode;
	buf[fsize] = 0;

	// Open directory

	DIR *dir = opendir(buf);

	if ( dir ){
		struct dirent *entry;
		while ( (entry=readdir(dir))!=0 ){

			/* If this is a valid name, add it to the list. */

			if ( strcmp(entry->d_name, ".")!=0 && strcmp(entry->d_name, "..")!=0 ){
				MediaInfo *mi = new MediaInfo(m_instance, (std::string(buf)+"\\"+entry->d_name).c_str());
				MediaInfo::MediaType mt = mi->GetMediaType();
				if ( mt==MediaInfo::MT_IMAGE || mt==MediaInfo::MT_VIDEO )
					m_files.push_back(mi);
				else delete mi;
				}
			}
		}
	delete[] buf;
}

Level::~Level() {
	std::vector<MediaInfo *>::iterator ii;
	for ( ii=m_files.begin() ; ii!=m_files.end() ; ii++ )
		delete *ii;
}

libvlc_media_t *Level::GetThis() {
	return libvlc_media_duplicate(m_files[m_index]->GetMedia());
}

libvlc_media_t *Level::StepNext() {
	int cnt = m_files.size();
	if ( cnt==1 )
		return libvlc_media_duplicate(m_files[m_index]->GetMedia());
	m_index++;
	if ( m_index>=cnt )
		m_index = 0;
	return libvlc_media_duplicate(m_files[m_index]->GetMedia());
}

libvlc_media_t *Level::StepPrev(){
	int cnt = m_files.size();
	if ( cnt==1 )
		return libvlc_media_duplicate(m_files[m_index]->GetMedia());
	m_index--;
	if ( m_index<0 )
		m_index = cnt-1;
	return libvlc_media_duplicate(m_files[m_index]->GetMedia());
}
