#include "graphics.hpp"
#include <iostream>
#include <cmath>
#include <string>

using namespace genv;
using namespace std;

const int XX = 500;
const int YY = 500;
const int FixX = 10;
const int FixY = 450;

const double K = 8.99E9;
const double Q = 0.05;


void circle(double x, double y, double r, char c) {
    for (int i = 0; i < 2*r; i++)
        for (int j = 0; j < 2*r; j++) {
            double dist = (r-i)*(r-i)+(r-j)*(r-j);
            if (dist < r*r)
                gout << move_to(x+i, y+j) << color(255-dist/r/r*100, 255-dist/r/r*100-c, 255-dist/r/r*100-c) << dot;
        }

    gout << move_to(x + r, y + 5) << color(0,0,0) << line(0,r*2 - 10);
    gout << move_to(x + 5, y + r) << line(r*2 - 10, 0);
}

class test {
private:
    double x,y;
    double vx, vy;
    double q;
    double m;
    int r;

    void mozog(int masik_x, int masik_y) {
        double F = K * Q * q / ((masik_x - x + r)*(masik_x - x + r) + (masik_y - y + r)*(masik_y - y + r));
        double alpha = atan((masik_y - y)/(masik_x - x));
        double ax = F*cos(alpha)/m;
        double ay = F*sin(alpha)/m;
        vx += ax;
        vy += ay;
        if (x < 0 or XX < x+r*2)
            vx *= -0.99;
        if (y < 0 or YY < y+r*2)
            vy *= -0.99;
        x += vx;
        y += vy;
    }
public:
    test(double _x, double _y, double _m, double _q) : x(_x), y(_y), m(_m*10 + 10), r(_m*2 + 10), q(_q), vx(0), vy(0) {}

    void rajzol(double masikX, double masikY) {
        mozog(masikX, masikY);
        circle(x, y, r, q/0.0001);
    }
};

void torol() {
    gout << move_to(0,0) << color(0,0,0) << box(XX, YY);
    circle(FixX, FixY, 20, 0);
    gout << move_to(10,20) << color(255, 255, 255) << text("Bal egergomb: test elhelyezese\nBalra-jobbra billyentu: toltes beallitasa\nFel-le billyentyu: tomeg beallitasa\nEnter: test inditasa\nSpace: uj teszt");
}

void rajzol(int x, int y, int r, int c) {
    torol();
    circle(x, y, r, c);
    gout << refresh;
}

void rajzol(test * T) {
    torol();
    T->rajzol(FixX, FixY);
    gout << refresh;
}

int main()
{
    gout.open(XX, YY);

    char status = 0;
    int x, y;
    double q = 0.001, m = 0;
    test * T;
    torol();
    gout << refresh;

    event ev;
    gin.timer(40);
    while(gin >> ev && ev.keycode != key_escape) {
        if (status == 0 and ev.type == ev_mouse and ev.button == 1) {
            x = ev.pos_x - 10;
            y = ev.pos_y - 10;
            status = 1;
            rajzol(x, y, 10, 0);
        }
        else if (status == 1 and ev.type == ev_key and ev.keycode == key_right) {
            q += 0.001;
            if (q > 0.01) q = 0.01;
            rajzol(x, y, m*2 + 10, q/0.0001);
        }
        else if (status == 1 and ev.type == ev_key and ev.keycode == key_left) {
            q -= 0.001;
            if (q < 0.001) q = 0.001;
            rajzol(x, y, m*2 + 10, q/0.0001);
        }
        else if (status == 1 and ev.type == ev_key and ev.keycode == key_up) {
            m++;
            if (m > 10) m = 10;
            rajzol(x, y, m*2 + 10, q/0.0001);
        }
        else if (status == 1 and ev.type == ev_key and ev.keycode == key_down) {
            m--;
            if (m < 0) m = 0;
            rajzol(x, y, m*2 + 10, q/0.0001);
        }
        else if (status == 1 and ev.type == ev_key and ev.keycode == key_enter) {
            status = 2;
            T = new test(x, y, m, q);
        }
        else if (status == 2 and ev.type == ev_timer)
            rajzol(T);
        else if (status == 2 and ev.type == ev_key and ev.keycode == key_space) {
            delete T;
            status = 0;
            m = 0;
            q =  0.001;
        }

        if(T) delete T;

    }

    return 0;
}
