package jguard.client.gui;

import cucky.jGuard.lib.LogFile;
import cucky.jGuard.lib.object.Map;
import cucky.jGuard.lib.object.MapObject;
import cucky.jGuard.lib.object.ObjectType;
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.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.RoundRectangle2D;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
import javax.imageio.ImageIO;
import jguard.client.Client;

public class PaintObject extends Rectangle {

    private int objId;
    private MapObject obj;

    private Image icon;
    private int x;
    private int y;
    private int boxX;
    private int boxY;

    private int paddingBoxu = 20;

    private int sirka;
    private int vyska;
    private RoundRectangle2D box;
    private Graphics2D g2;
    private Boolean selected = false;

    private Font fontNormal12 = new Font("Arial", Font.PLAIN, 12);
    private Font fontBold12 = new Font("Arial", Font.BOLD, 12);
    private Font fontNormalSmall = new Font("Arial", Font.PLAIN, 10);

    public PaintObject(int objId) {
        this.objId = objId;

        refresh_data();

        prepocitat_rozmery();

    }
    
    private void refresh_data() {
        // ziskani objektu
        for (Map map : Client.map) {
            for (MapObject object : map.getObjects()) {
                if (object.getId() == objId) {
                    this.obj = object;
                    
                }
            }
        }
    }

    private void prepocitat_rozmery() {
        // vyska boxu
        vyska = 5; // padding top
        if (this.icon != null) {
            vyska += this.icon.getHeight(null); // vyska obrazku
        }
        vyska += getStringHeight(fontBold12); // vyska prvniho radku
        if (!obj.getIp().equals("")) {
            vyska += 5; // mezera mezi radky 
            vyska += getStringHeight(fontNormal12); // vyska druhyho radku 
        }
/*        
        for (SnmpProbe snmpProbe : obj.getSnmpProbe()) {
            if (snmpProbe.isView()) {
                vyska += 5; // mezera mezi radky 
                vyska += getStringHeight(fontNormalSmall);
            }
        }
*/        
        vyska += 5; // padding bottom

        //sirka boxu
        List<Integer> sList = new ArrayList<Integer>();
        sList.add(getStringWidth(obj.getName(), fontBold12) + paddingBoxu);
        sList.add(getStringWidth(obj.getIp(), fontNormal12) + paddingBoxu);
/*        
        for (SnmpProbe snmpProbe : obj.getSnmpProbe()) {
            if (snmpProbe.isView()) {
                sList.add(getStringWidth(snmpProbe.getName() + "+ " + snmpProbe.getValue(), fontNormal12) + paddingBoxu);
            }
        }
*/
        sirka = Collections.max(sList);
    }


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

        // nastaveni pozice x, y objektu
        this.x = obj.getX();
        this.y = obj.getY();
        
        refresh_data();

        // nastaveni ikony objektu
        try {
            for (ObjectType objectType : Client.deviceType) {
                if (objectType.getId() == obj.getType()) {
                    byte[] decodedBytes = Base64.getDecoder().decode(objectType.getImgStr());
                    ByteArrayInputStream bis = new ByteArrayInputStream(decodedBytes);
                    this.icon = ImageIO.read(bis);
                    break;
                }
            }
        } catch (IOException ex) {
            LogFile.printErr("Object icon exception: " + ex.getMessage());
        }

        prepocitat_rozmery();

        /* TODO box gradient
        GradientPaint redtowhite = new GradientPaint(x, y, Color.red, 200, y,Color.blue);
        g2.setPaint(redtowhite);
         */
        // status objektu
        switch (obj.getStatus()) {
            case 1: // online
                g2.setPaint(new Color(83, 241, 83));
                break;
            case 2: // warning
                g2.setPaint(new Color(255, 131, 0));
                break;
            case 3: // offline
                g2.setPaint(new Color(221, 63, 63));
                break;
            default: // other
                g2.setPaint(new Color(172, 172, 172));
        }

        // vypocitani pocatecnich souradnic
        boxX = x - (sirka / 2);
        boxY = y - (vyska / 2);

        // vykresleni boxu
        box = new RoundRectangle2D.Double(boxX, boxY, sirka, vyska, 10, 10);
        g2.fill(box);

        if (selected) {
            g2.setStroke(new BasicStroke(1.5f));
            g2.setColor(Color.BLACK);
            g2.draw(box);
        }
        //

        // nacteni ikonka zarizeni
        if (icon != null) {
            int imgX = boxX + sirka / 2 - (icon.getWidth(null) / 2);
            int imgY = boxY + 5;
            g.drawImage(icon, imgX, imgY, null);
            boxY += icon.getHeight(null); // pricte vysku ikonky
        } else {

        }

        // vypsani nazvu prvku
        g2.setPaint(Color.BLACK);
        g2.setFont(fontBold12);
        g2.drawString(obj.getName(), boxX + (int) (box.getWidth() / 2) - (getStringWidth(obj.getName(), g2.getFont()) / 2), boxY + getStringHeight(g2.getFont()));

        // vypsani ip prvku
        boxY += 20;
        g2.setFont(fontNormal12);
        g2.drawString(obj.getIp(), boxX + (int) (box.getWidth() / 2) - (getStringWidth(obj.getIp(), g2.getFont()) / 2), boxY + getStringHeight(g2.getFont()));

        // vypsani snmp sond
        g2.setFont(fontNormalSmall);
/*        
        for (SnmpProbe snmpProbe : obj.getSnmpProbe()) {
            if (snmpProbe.isView()) {
                boxY += 20;
                String str = snmpProbe.getName() + ": " + snmpProbe.getValue();
                g2.drawString(str, boxX + (int) (box.getWidth() / 2) - (getStringWidth(str, g2.getFont()) / 2), boxY + getStringHeight(g2.getFont()));
            }
        }
*/
        this.setBounds(boxX, boxY, sirka, vyska);

    }

    public int getBoxX() {
        return (int) box.getX();
    }

    public int getBoxY() {
        return (int) box.getY();
    }

    @Override
    public double getX() {
        return x;
    }

    @Override
    public double getY() {
        return y;
    }

    public int getBoxWidth() {
        return sirka;
    }

    public int getBoxHeight() {
        return vyska;
    }

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

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

    private int getStringHeight(Font font) {
        Canvas c = new Canvas();
        FontMetrics fm = c.getFontMetrics(font);
        return fm.getHeight();
    }

    @Override
    public boolean contains(Point p) {
        if ((box.getMinX() < p.getX() && p.getX() < box.getMaxX()) && (box.getMinY() < p.getY() && p.getY() < box.getMaxY())) {
            return true;
        } else {
            return false;
        }
    }

    public void setPosition(Point p) {
        obj.setX(p.x + sirka / 2);
        obj.setY(p.y + vyska / 2);
    }

    public int getId() {
        return obj.getId();
    }

    public MapObject getObject() {
        return obj;
    }

    public Point getPoint() {
        Point p = new Point();
        p.x = this.x;
        p.y = this.y;
        return p;
    }

}
