package jguard.client.gui;

import cucky.jGuard.lib.object.Map;
import cucky.jGuard.lib.object.ObjectConnection;
import java.awt.BasicStroke;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Line2D;
import java.awt.geom.RoundRectangle2D;
import java.text.DecimalFormat;
import jguard.client.Client;

public class PaintConnection extends Rectangle {

    private Point from = null;
    private Point to = null;
    private Font font = new Font("Helvetica", Font.PLAIN, 10);

    private int idConnection;
    private ObjectConnection connection;
    private boolean selected = true;

    private int xObdelnik, x2Obdelnik, yObdelnik, y2Obdelnik;

    public PaintConnection(int idConnection) {
        this.idConnection = idConnection;
        refresh_data();

    }

    private void refresh_data() {
        // ziskani objektu
        for (Map map : Client.map) {
            for (ObjectConnection c : map.getConnection()) {
                if (c.getId() == this.idConnection) {
                    // nastaveni objektu
                    this.connection = c;
                    // nasteveni souradnic
                    for (PaintObject i : MapView.items) {
                        if (i.getId() == c.getFrom()) {
                            this.from = i.getPoint();
                        }
                        if (i.getId() == c.getTo()) {
                            this.to = i.getPoint();
                        }
                    }
                }
            }
        }
    }

    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        refresh_data();

        // vykresli line
        // TODO typ cary podle typu spojeni (1000, 100, 10, vlan, ...) 
        switch (connection.getType()) {
            case ObjectConnection.TYPE_WIRELLES:
                float[] dashingPattern = {2f, 2f};
                g2.setStroke(new BasicStroke(2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, dashingPattern, 2.0f));
                break;
            case ObjectConnection.TYPE_GE:
                g2.setStroke(new BasicStroke(5));
                break;
            case ObjectConnection.TYPE_FE:
                g2.setStroke(new BasicStroke(3));
                break;
            case ObjectConnection.TYPE_E:
                g2.setStroke(new BasicStroke(1));
                break;
            case ObjectConnection.TYPE_10G_FIBER:
                g2.setStroke(new BasicStroke(5)); // TODO doresit tvar cary
                break;
            case ObjectConnection.TYPE_1G_FIBER:
                g2.setStroke(new BasicStroke(5)); // TODO doresit tvar cary
                break;
            case ObjectConnection.TYPE_100M_FIBER:
                g2.setStroke(new BasicStroke(5)); // TODO doresit tvar cary
                break;
        }

        if (selected) {
            // TODO zvyrazneni cary pri vybrani propojeni 
        }

        g2.draw(new Line2D.Double(this.from, this.to));

        // vypocita stred cary
        Point centerPoint = midpoint(this.from.getX(), this.to.getX(), this.from.getY(), this.to.getY());

        // zmeni na sedou barvu
        g2.setPaint(new Color(170, 170, 170));

        if (connection.isRead()) {

            // vyska, sirka
            int sirka = 80;
            int vyska = 30;

            // vypocitani pocatecnich bodu
            int x = centerPoint.x - sirka / 2;
            int y = centerPoint.y - vyska / 2;

            // TODO az bude vyresni detekce kliku na caru tak tyto promenen uplne zrusit 
            xObdelnik = x;
            x2Obdelnik = x + sirka;
            yObdelnik = y;
            y2Obdelnik = y + vyska;

            // vykresli oblast pro rx, tx
            RoundRectangle2D.Double box = new RoundRectangle2D.Double(x, y, sirka, vyska, 10, 10);
            g2.fill(box);

            // zmeni barvu na cernou
            g2.setPaint(new Color(0, 0, 0));

            // nastavi font
            g2.setFont(font);
            // vypise TX
            String tx = "Tx: " + formatFileSize(connection.getTx());
            g2.drawString(tx, x + (int) (box.getWidth() / 2) - (getStringWidth(tx) / 2), y + 12);

            // vypise RX
            String rx = "Rx: " + formatFileSize(connection.getRx());
            g2.drawString(rx, x + (int) (box.getWidth() / 2) - (getStringWidth(rx) / 2), y + 24);
        }
    }

    private Point midpoint(double x1, double x2, double y1, double y2) {
        Point p = new Point((int) (x1 + x2) / 2, (int) (y1 + y2) / 2);
        return p;
    }

    private int getStringWidth(String text) {
        //return g.getFontMetrics().stringWidth(text);
        Canvas c = new Canvas();
        FontMetrics fm = c.getFontMetrics(font);
        return fm.stringWidth(text);
    }

    public void setSelected(Boolean value) {
        this.selected = value;
    }

    public ObjectConnection getObjectConnection() {
        return connection;
    }

    @Override
    public boolean contains(Point p) {
        if ((xObdelnik < p.getX() && p.getX() < x2Obdelnik) && (yObdelnik < p.getY() && p.getY() < y2Obdelnik)) {
            return true;
        } else {
            return false;
        }
    }

    public static String formatFileSize(long size) {
        String hrSize = null;
        double b = size;
        double k = size / 1024.0;
        double m = ((size / 1024.0) / 1024.0);
        double g = (((size / 1024.0) / 1024.0) / 1024.0);
        double t = ((((size / 1024.0) / 1024.0) / 1024.0) / 1024.0);

        DecimalFormat dec = new DecimalFormat("0.00");

        if (t > 1) {
            hrSize = dec.format(t).concat(" TB");
        } else if (g > 1) {
            hrSize = dec.format(g).concat(" GB");
        } else if (m > 1) {
            hrSize = dec.format(m).concat(" MB");
        } else if (k > 1) {
            hrSize = dec.format(k).concat(" KB");
        } else {
            hrSize = dec.format(b).concat(" Bytes");
        }

        return hrSize;
    }

}
