#include "edit.h"

Editor::Editor()
: m_multi( MULTI_DEFAULT ), m_last_save( 0 ), m_help( true ), m_leftPoint( 1 ),
m_index("Niveaux/Level.idx"), m_name(NAME_DEFAULT),
m_screen(nullptr)
{
	// Construire les trois points de base
	m_vx.push_back(0.0f);
	m_vy.push_back(-1.0f);

	m_vx.push_back(0.0f);
	m_vy.push_back(0.0f);

	m_vx.push_back(6.0f);
	m_vy.push_back(0.0f);

}

Editor::~Editor()
{
	if ( m_screen )
		SDL_FreeSurface( m_screen );
}

bool Editor::init()
{
	m_screen = SDL_SetVideoMode(1366, 768, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
    if ( !m_screen )
    {
        std::cout << "Unable to set 1366x768 video: " << SDL_GetError() << std::endl;
        return false;
    }

    return true;
}


void Editor::addPlot( int ex, int ey )
{
	// Change coordinates
	float fx( 1.0f / m_multi * ex);
	float fy( 1.0f / m_multi * ey);

	// Create a plot
	if ( fx > m_vx.back() )
	{
		m_vx.push_back(fx);
		m_vy.push_back(fy);

		return;
	}

	// Move a point
	unsigned int id_mov( m_leftPoint );
	float dist1( abs(m_vx[id_mov] - fx) );
	float dist2;

	if ( id_mov < m_vx.size() - 1 )
	{
		dist2 = abs(m_vx[id_mov + 1] - fx);

		while ( id_mov < m_vx.size() - 1 && dist2 <= dist1 )
		{
			dist1 = dist2;
			id_mov++;
			dist2 = abs(m_vx[id_mov] - fx);
		}

		if ( id_mov > 3 )
			id_mov --;
		else
			return;
	}

	m_vx[id_mov] = fx;
	m_vy[id_mov] = fy;

}

void Editor::removePlot()
{
	if ( m_vx.size() > 3 )
	{
		m_vx.pop_back();
		m_vy.pop_back();
	}
}


void Editor::zoomIn()
{
	m_multi += 25;
}

void Editor::zoomOut()
{
	if ( m_multi > 25 )
		m_multi -= 25;
}


void Editor::draw( int ix, int iy )
{
	// Variables
	Sint16 x1, y1, x2, y2;
	float fx( 1.0f / m_multi * ix);
	float fy( 1.0f / m_multi * iy);

	// Incrément
	unsigned int i(m_leftPoint);

	// Recherche du premier hors champ vers la gauche depuis le dernier point connu
	while ( i > 1 && m_vx[i] > fx )
		i --;

	// Recherche du premier point dans le champ
	while ( m_vx[i] < fx && i < m_vx.size() )
		i ++;

	// Mise a jour de l'indice optimal
	m_leftPoint = i;
	if ( m_leftPoint > 1 && m_leftPoint >= m_vx.size() )
		m_leftPoint = m_vx.size() - 1;

	// Premiers points du polygone
	x1 = ( m_vx[i-1] - fx ) * m_multi;
	y1 = ( m_vy[i-1] - fy ) * m_multi;

	// Nettoyage
    SDL_FillRect(m_screen, 0, SDL_MapRGB(m_screen->format, 0, 0, 128));

	// Dessin des points visibles
	for ( ; i < m_vx.size() && x1 < m_screen->w ; i++ )
	{
		x2 = ( m_vx[i] - fx ) * m_multi;
		y2 = ( m_vy[i] - fy ) * m_multi;

		lineRGBA( m_screen, x1, y1, x2, y2, 255, 255, 0, 255);

		x1 = x2;
		y1 = y2;
	}

	// Repère pour le liner
	rectangleRGBA( m_screen, 100, 323, 100 + m_multi * 150 / 100, 323 + m_multi * 71 / 100, 255, 128, 0, 255 );

	// Infos
	if ( m_help )
	{
		stringRGBA(m_screen, 16, 7, ("Nom de niveau : " + m_name).c_str(), 0, 255, 0, 255 );
		stringRGBA(m_screen, 16, 16, ("Deniere sauvegarde : " + std::to_string(m_last_save)).c_str(), 0, 255, 0, 255 );
		stringRGBA(m_screen, 16, 25, ("Zoom : " + std::to_string(m_multi)).c_str(), 0, 255, 0, 255 );

		stringRGBA(m_screen, 16, 35, "Sauvegarder : s", 0, 255, 0, 255);
		stringRGBA(m_screen, 16, 44, "Detruire dernier point : z", 0, 255, 0, 255);
		stringRGBA(m_screen, 16, 53, "Deplacer camera : clic droit", 0, 255, 0, 255);
		stringRGBA(m_screen, 16, 62, "Ajoute point : clic gauche", 0, 255, 0, 255);
		stringRGBA(m_screen, 16, 71, "Activer ou desactiver l'aide : h", 0, 255, 0, 255);
		stringRGBA(m_screen, 16, 80, "Charger un niveau : c", 0, 255, 0, 255);
	}

	// Actualisation
    SDL_Flip(m_screen);
}


void Editor::save()
{
	// Nom de niveau
	if ( m_name == NAME_DEFAULT )
		SF_keyName( m_name, m_screen );
	
	// Nom de fichier
    std::string chemin( m_name + EXT );

    // Index update
    SF_addFile( m_index, chemin );

    // Chemin
    chemin = FOLDER + chemin;

    // Flux
    std::ofstream writeStream( chemin.c_str() );

    // Ecriture
    for ( unsigned int i(0); i < m_vx.size(); i ++ )
        writeStream << m_vx[i] << ' ' << m_vy[i] << std::endl;

    // Sauvegardé !
    m_last_save = SDL_GetTicks();
}

void Editor::load()
{
	// Pick up a level
	std::string chemin;
	SF_choose( m_index, chemin, m_screen );

	// If given up
	if ( chemin == "" )
		return;
	else
	{
		chemin.erase( chemin.size() - 4 );
		m_name = chemin;
	}

	// Flux
	chemin = FOLDER + chemin + EXT;
	std::ifstream loadStream( chemin.c_str() );

    // Lecture
    float buff;

    std::vector<float> data;

    while ( loadStream >> buff )
		data.push_back( buff );

	loadStream.close();

	// Remplacment
	if ( !m_vx.empty() )
	{
		m_vx.clear();
		m_vy.clear();
	}

	// Remplissage
	for ( unsigned int i(0); i < data.size() / 2; i++ )
	{
		m_vx.push_back( data[2*i] );
		m_vy.push_back( data[2*i + 1] );
	}
}

void Editor::toggleHelp()
{
	m_help = !m_help;
}