#include "controlpanel.h"

#include "raylib.h"
#include "raymath.h"

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// Tools
void printVector2( Vector2 v )
{
    printf( "[%3f, %3f]", v.x, v.y );
}

// Constructor / Destructor
Panel * Panel_new()
{
    Panel * p = malloc( sizeof(Panel) );
    return p;
}

void Panel_delete(Panel * self)
{
    free(self);
}

// Initialization
void Panel_initialize(Panel * self, NetWorld * world)
{
    self->world= world;
    self->camera.x= 0.f;
    self->camera.y= 0.f;
    self->screenCenter.x= 400.f;
    self->screenCenter.y= 300.f;
    self->scale= 10.f; //pixel per meters
}

// To String
void Panel_print(Panel * self)
{
    printf( "Panel camera(x-%f, y-%f, scale-%f)\n",
            self->camera.x,
            self->camera.y,
            self->scale);
}

// Rendering
void Panel_draw(Panel * self)
{
    BeginDrawing();
    ClearBackground(RAYWHITE);
    
    // Draw the edges for each nodes:
    for(int i= 0 ; i < self->world->size ; ++i )
    {
        Node * n= &(self->world->nodes[i]);
        for(int j= 0 ; j < n->card ; ++j )
            Panel_drawEdge( self, &(n->edges[j]) );
    }

    // Draw the nodes
    for(int i= 0 ; i < self->world->size ; ++i )
    {
        Panel_drawNode( self, &(self->world->nodes[i]) );
    }
    Panel_drawBasis(self);
    EndDrawing(); 
}

void Panel_drawBasis(Panel * self)
{
    Vector2 screen00= {0.f, 0.f};
    screen00= Panel_pixelFromPosition(self, &( screen00 ) );
    Vector2 screen10= {1.f, 0.f};
    screen10= Panel_pixelFromPosition(self, &( screen10 ) );
    Vector2 screen01= {0.f, 1.f}; 
    screen01= Panel_pixelFromPosition(self, &( screen01 ) );
    DrawCircleV( screen00, 4, BLUE );   
    DrawLineV( screen00, screen10, RED );
    DrawLineV( screen00, screen01, BLUE );
}

void Panel_drawNode(Panel * self, Node * n)
{
    Vector2 screenPosition= Panel_pixelFromPosition(self, &(n->position) );
    DrawCircleV(screenPosition, 24, n->color);
    DrawCircleV(screenPosition, 20, RAYWHITE);
    DrawText(n->name, (int)(screenPosition.x), (int)(screenPosition.y), 20, n->color);
}

void Panel_drawEdge(Panel * self, Edge * e)
{
    Vector2 source= Panel_pixelFromPosition(self, &(e->_source->position) );
    Vector2 target= Panel_pixelFromPosition(self, &(e->_target->position) );

    Vector2 ortho= (Vector2){ target.x-source.x, target.y-source.y }; // Vector from Source to Target

    float ratio= 10.f / Vector2Length( ortho );
    ortho= (Vector2){ -ortho.y*ratio, ortho.x*ratio };// 10 ortho-normal vector from v 

    Vector2 source1= (Vector2){source.x-ortho.x, source.y-ortho.y};
    Vector2 source2= (Vector2){source.x+ortho.x, source.y+ortho.y};

    DrawTriangle(source1, source2, target, e->color);
}

Vector2 Panel_pixelFromPosition(Panel * self, Vector2 * p)
{
    Vector2 pixel= {
        self->screenCenter.x + (p->x - self->camera.x ) * self->scale,
        self->screenCenter.y - (p->y - self->camera.y ) * self->scale
    };
    return pixel;
}

Vector2 Panel_positionFromPixel(Panel * self, Vector2 * p)
{
    Vector2 position= { p->x, p->y };
    return position;
}

void Panel_control(Panel * self)
{
    Panel_controlCamera(self);
}

void Panel_controlCamera(Panel * self)
{
    // KEYBOARD Control:
    float step= 3.0f / self->scale;
    if (IsKeyDown(KEY_RIGHT)) self->camera.x += step;
    if (IsKeyDown(KEY_LEFT)) self->camera.x -= step;
    if (IsKeyDown(KEY_UP)) self->camera.y += step;
    if (IsKeyDown(KEY_DOWN)) self->camera.y -= step;

    self->scale += (GetMouseWheelMove()*1.f);
    self->scale = fmaxf( self->scale, 0.001f );
}