package teamdev.jxcapture.samples.demo;

import javax.swing.*;
import javax.swing.plaf.BorderUIResource;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ResourceBundle;

/**
 * @author Ikryanov Vladimir
 */
public class HelperComponent extends JComponent {

    private static final int ZOOM_VALUE = 5;
    private static final int IMAGE_SIZE = 180;
    private static final int BORDER_OFFSET = IMAGE_SIZE / ZOOM_VALUE;
    private static final int AREA_OFFSET = BORDER_OFFSET / 2;

    private final Color borderColor1 = new Color(105, 105, 105);
    private final Color borderColor2 = new Color(210, 210, 210);
    private final Color backgroundColor = new Color(149, 149, 149);

    private BufferedImage backgroundImage;
    private Image currentThumbnail;
    private Rectangle currentRect = new Rectangle();
    private Point currentPoint = new Point();
    private JLabel navigationBar = new JLabel();

    public HelperComponent(BufferedImage image) {
        int width = image.getWidth() + BORDER_OFFSET;
        int height = image.getHeight() + BORDER_OFFSET;

        backgroundImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics graphics = backgroundImage.getGraphics();
        graphics.drawImage(image, AREA_OFFSET, AREA_OFFSET, null);

        Dimension size = new Dimension(200, 370);
        setPreferredSize(size);
        setSize(size);
        createHelpPane();
        updateNavigationBar();
    }

    public void updateComponent(Point point, Rectangle rect) {
        currentPoint = point;
        currentRect = rect;
        updateNavigationBar();
        updateThumbnail();
    }

    private void createHelpPane() {
        setBorder(new BorderUIResource.EmptyBorderUIResource(200, 10, 10, 10));
        setLayout(new BorderLayout());
        ResourceBundle resource = ApplicationSettings.getResourceBundle();
        JPanel contentPane = new JPanel(new GridBagLayout());
        contentPane.setOpaque(false);
        JLabel selection1Label = new JLabel(resource.getString("HelpDialog.Label.Selection1.Text"));
        JLabel selection2Label = new JLabel(resource.getString("HelpDialog.Label.Selection2.Text"));
        JLabel cancelLabel = new JLabel(resource.getString("HelpDialog.Label.Cancel.Text"));
        JLabel helpLabel = new JLabel(resource.getString("HelpDialog.Label.Help.Text"));
        selection1Label.setForeground(Color.WHITE);
        selection2Label.setForeground(Color.WHITE);
        cancelLabel.setForeground(Color.WHITE);
        helpLabel.setForeground(Color.DARK_GRAY);
        navigationBar.setHorizontalAlignment(SwingConstants.CENTER);
        navigationBar.setForeground(Color.WHITE);
        contentPane.add(navigationBar,
                new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
                        GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 0), 0, 0));
        contentPane.add(selection1Label,
                new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST,
                        GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
        contentPane.add(selection2Label,
                new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST,
                        GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
        contentPane.add(cancelLabel,
                new GridBagConstraints(0, 3, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST,
                        GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
        contentPane.add(helpLabel,
                new GridBagConstraints(0, 4, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
                        GridBagConstraints.HORIZONTAL, new Insets(10, 0, 0, 0), 0, 0));
        contentPane.add(Box.createVerticalGlue(),
                new GridBagConstraints(0, 5, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER,
                        GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
        add(contentPane, BorderLayout.CENTER);
    }

    private void updateThumbnail() {
        if (currentThumbnail != null) {
            currentThumbnail.flush();
            currentThumbnail = null;
        }
        currentThumbnail = createThumbnail(currentPoint, currentRect, IMAGE_SIZE);
        repaint();
    }

    private void updateNavigationBar() {
        navigationBar.setText("<html><b><p align='center'>X = " + currentPoint.x + ", Y = " + currentPoint.y +
                "</p>Width = " + currentRect.width + ", Height = " + currentRect.height);
    }

    private Image createThumbnail(Point point, Rectangle rect, int size) {
        int offsetX = point.x;
        int offsetY = point.y;
        // draw rectangle
        drawSelectedRect(rect);
        // create thumbnail image
        BufferedImage image = backgroundImage.getSubimage(offsetX, offsetY, BORDER_OFFSET, BORDER_OFFSET);
        BufferedImage subImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics g = subImage.getGraphics();
        g.drawImage(image, 0, 0, null);
        // cleare rect paint
        drawSelectedRect(rect);
        if (rect.isEmpty()) {
            // draw cursor
            g.setXORMode(Color.RED);
            // draw vertical line
            g.drawLine(AREA_OFFSET, AREA_OFFSET - 5, AREA_OFFSET, AREA_OFFSET + 5);
            // draw horisontal line
            g.drawLine(AREA_OFFSET - 5, AREA_OFFSET, AREA_OFFSET + 5, AREA_OFFSET);
        }

        return subImage.getScaledInstance(size, size, BufferedImage.SCALE_FAST);
    }

    private void drawSelectedRect(Rectangle rect) {
        if (!rect.isEmpty()) {
            Graphics graphics = backgroundImage.getGraphics();
            graphics.setXORMode(Color.BLACK);
            graphics.drawRect(rect.x + AREA_OFFSET, rect.y + AREA_OFFSET, rect.width, rect.height);
        }
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Rectangle rect = getBounds();

        // draw border
        g.setColor(borderColor1);
        g.drawRect(rect.x, rect.y, rect.width - 1, rect.height - 1);
        g.setColor(borderColor2);
        g.drawRect(rect.x + 1, rect.y + 1, rect.width - 3, rect.height - 3);
        g.setColor(backgroundColor);
        g.fillRect(rect.x + 2, rect.y + 2, rect.width - 4, rect.height - 4);

        // draw thumbnail
        if (currentThumbnail != null) {
            g.drawImage(currentThumbnail, 10, 10, null);
        }
    }
}