package com.android.hierarchyviewer.ui;

import com.android.ddmlib.IDevice;
import com.android.ddmlib.RawImage;
import com.android.hierarchyviewer.scene.ViewNode;
import com.android.hierarchyviewer.ui.util.IconLoader;
import com.android.hierarchyviewer.ui.util.PngFileFilter;
import com.android.hierarchyviewer.util.WorkerThread;

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutionException;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

class ScreenViewer extends JPanel implements ActionListener {
    private final Workspace workspace;
    private final IDevice device;

    private GetScreenshotTask task;
    private BufferedImage image;
    private int[] scanline;
    private volatile boolean isLoading;

    private BufferedImage overlay;
    private AlphaComposite overlayAlpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f);

    private ScreenViewer.LoupeStatus status;
    private ScreenViewer.LoupeViewer loupe;
    private ScreenViewer.Crosshair crosshair;

    private int zoom = 8;
    private int y = 0;

    private Timer timer;
    private ViewNode node;

    private JSlider zoomSlider;

    ScreenViewer(Workspace workspace, IDevice device, int spacing) {
        setLayout(new GridBagLayout());
        setOpaque(false);

        this.workspace = workspace;
        this.device = device;

        timer = new Timer(5000, this);
        timer.setInitialDelay(0);
        timer.setRepeats(true);

        JPanel panel = buildViewerAndControls();
        add(panel, new GridBagConstraints(0, 0, 1, 1, 0.3f, 1.0f,
                GridBagConstraints.FIRST_LINE_START, GridBagConstraints.BOTH,
                new Insets(0, 0, 0, 0), 0, 0));

        JPanel loupePanel = buildLoupePanel(spacing);
        add(loupePanel, new GridBagConstraints(1, 0, 1, 1, 0.7f, 1.0f,
                GridBagConstraints.FIRST_LINE_START, GridBagConstraints.BOTH,
                new Insets(0, 0, 0, 0), 0, 0));

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                timer.start();
            }
        });
    }

    private JPanel buildLoupePanel(int spacing) {
        loupe = new LoupeViewer();
        loupe.addMouseWheelListener(new WheelZoomListener());
        CrosshairPanel crosshairPanel = new CrosshairPanel(loupe);

        JPanel loupePanel = new JPanel(new BorderLayout());
        loupePanel.add(crosshairPanel);
        status = new LoupeStatus();
        loupePanel.add(status, BorderLayout.SOUTH);

        loupePanel.setBorder(BorderFactory.createEmptyBorder(0, spacing, 0, 0));
        return loupePanel;
    }

    private class WheelZoomListener implements MouseWheelListener {
        public void mouseWheelMoved(MouseWheelEvent e) {
            if (zoomSlider != null) {
                int val = zoomSlider.getValue();
                val -= e.getWheelRotation() * 2;
                zoomSlider.setValue(val);
            }
        }
    }

    private JPanel buildViewerAndControls() {
        JPanel panel = new JPanel(new GridBagLayout());
        crosshair = new Crosshair(new ScreenshotViewer());
        crosshair.addMouseWheelListener(new WheelZoomListener());
        JScrollPane scroller = new JScrollPane(crosshair);
        scroller.setPreferredSize(new Dimension(320, 480));
        scroller.setBorder(null);
        panel.add(scroller,
                new GridBagConstraints(0, y++, 2, 1, 1.0f, 1.0f,
                    GridBagConstraints.FIRST_LINE_START, GridBagConstraints.BOTH,
                    new Insets(0, 0, 0, 0), 0, 0));
        buildSlider(panel, "Overlay:", "0%", "100%", 0, 100, 30, 1).addChangeListener(
                new ChangeListener() {
                    public void stateChanged(ChangeEvent event) {
                        float opacity = ((JSlider) event.getSource()).getValue() / 100.0f;
                        overlayAlpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity);
                        repaint();
                    }
        });
        buildOverlayExtraControls(panel);
        buildSlider(panel, "Refresh Rate:", "1s", "40s", 1, 40, 5, 1).addChangeListener(
                new ChangeListener() {
                    public void stateChanged(ChangeEvent event) {
                        int rate = ((JSlider) event.getSource()).getValue() * 1000;
                        timer.setDelay(rate);
                        timer.setInitialDelay(0);
                        timer.restart();
                    }
        });
        zoomSlider = buildSlider(panel, "Zoom:", "2x", "24x", 2, 24, 8, 2);
        zoomSlider.addChangeListener(
                new ChangeListener() {
                    public void stateChanged(ChangeEvent event) {
                        zoom = ((JSlider) event.getSource()).getValue();
                        loupe.clearGrid = true;
                        loupe.moveToPoint(crosshair.crosshair.x, crosshair.crosshair.y);
                        repaint();
                    }
        });
        panel.add(Box.createVerticalGlue(),
                new GridBagConstraints(0, y++, 2, 1, 1.0f, 1.0f,
                    GridBagConstraints.FIRST_LINE_START, GridBagConstraints.NONE,
                    new Insets(0, 0, 0, 0), 0, 0));
        return panel;
    }

    private void buildOverlayExtraControls(JPanel panel) {
        JPanel extras = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));

        JButton loadOverlay = new JButton("Load...");
        loadOverlay.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                SwingWorker<?, ?> worker = openOverlay();
                if (worker != null) {
                    worker.execute();
                }
            }
        });
        extras.add(loadOverlay);

        JCheckBox showInLoupe = new JCheckBox("Show in Loupe");
        showInLoupe.setSelected(false);
        showInLoupe.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                loupe.showOverlay = ((JCheckBox) event.getSource()).isSelected();
                loupe.repaint();
            }
        });
        extras.add(showInLoupe);

        panel.add(extras, new GridBagConstraints(1, y++, 1, 1, 1.0f, 0.0f,
                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
                        new Insets(0, 0, 0, 0), 0, 0));
    }

    public SwingWorker<?, ?> openOverlay() {
        JFileChooser chooser = new JFileChooser();
        chooser.setFileFilter(new PngFileFilter());
        int choice = chooser.showOpenDialog(this);
        if (choice == JFileChooser.APPROVE_OPTION) {
            return new OpenOverlayTask(chooser.getSelectedFile());
        } else {
            return null;
        }
    }

    private JSlider buildSlider(JPanel panel, String title, String minName, String maxName,
            int min, int max, int value, int tick) {
        panel.add(new JLabel(title), new GridBagConstraints(0, y, 1, 1, 1.0f, 0.0f,
                    GridBagConstraints.LINE_END, GridBagConstraints.NONE,
                    new Insets(0, 0, 0, 6), 0, 0));
        JPanel sliderPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
        sliderPanel.add(new JLabel(minName));
        JSlider slider = new JSlider(min, max, value);
        slider.setMinorTickSpacing(tick);
        slider.setMajorTickSpacing(tick);
        slider.setSnapToTicks(true);
        sliderPanel.add(slider);
        sliderPanel.add(new JLabel(maxName));
        panel.add(sliderPanel, new GridBagConstraints(1, y++, 1, 1, 1.0f, 0.0f,
                    GridBagConstraints.FIRST_LINE_START, GridBagConstraints.NONE,
                        new Insets(0, 0, 0, 0), 0, 0));
        return slider;
    }

    void stop() {
        timer.stop();
    }

    void start() {
        timer.start();
    }

    void select(ViewNode node) {
        this.node = node;
        repaint();
    }

    class LoupeViewer extends JComponent {
        private final Color lineColor = new Color(1.0f, 1.0f, 1.0f, 0.3f);

        private int width;
        private int height;
        private BufferedImage grid;
        private int left;
        private int top;
        public boolean clearGrid;

        private final Rectangle clip = new Rectangle();
        private boolean showOverlay = false;

        LoupeViewer() {
            addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent event) {
                    moveToPoint(event);
                }
            });
            addMouseMotionListener(new MouseMotionAdapter() {
                @Override
                public void mouseDragged(MouseEvent event) {
                    moveToPoint(event);
                }
            });
        }

        @Override
        protected void paintComponent(Graphics g) {
            if (isLoading) {
                return;
            }

            g.translate(-left, -top);

            if (image != null) {
                Graphics2D g2 = (Graphics2D) g.create();
                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                        RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
                g2.scale(zoom, zoom);
                g2.drawImage(image, 0, 0, null);
                if (overlay != null && showOverlay) {
                    g2.setComposite(overlayAlpha);
                    g2.drawImage(overlay, 0, image.getHeight() - overlay.getHeight(), null);
                }
                g2.dispose();
            }

            int width = getWidth();
            int height = getHeight();

            Graphics2D g2 = null;
            if (width != this.width || height != this.height) {
                this.width = width;
                this.height = height;

                grid = new BufferedImage(width + zoom + 1, height + zoom + 1,
                        BufferedImage.TYPE_INT_ARGB);
                clearGrid = true;
                g2 = grid.createGraphics();
            } else if (clearGrid) {
                g2 = grid.createGraphics();
                g2.setComposite(AlphaComposite.Clear);
                g2.fillRect(0, 0, grid.getWidth(), grid.getHeight());
                g2.setComposite(AlphaComposite.SrcOver);
            }

            if (clearGrid) {
                clearGrid = false;

                g2.setColor(lineColor);
                width += zoom;
                height += zoom;

                for (int x = zoom; x <= width; x += zoom) {
                    g2.drawLine(x, 0, x, height);
                }

                for (int y = 0; y <= height; y += zoom) {
                    g2.drawLine(0, y, width, y);
                }

                g2.dispose();
            }

            if (image != null) {
                g.getClipBounds(clip);
                g.clipRect(0, 0, image.getWidth() * zoom + 1, image.getHeight() * zoom + 1);
                g.drawImage(grid, clip.x - clip.x % zoom, clip.y - clip.y % zoom, null);
            }

            g.translate(left, top);
        }

        void moveToPoint(MouseEvent event) {
            int x = Math.max(0, Math.min((event.getX() + left) / zoom, image.getWidth() - 1));
            int y = Math.max(0, Math.min((event.getY() + top) / zoom, image.getHeight() - 1));
            moveToPoint(x, y);
            crosshair.moveToPoint(x, y);
        }

        void moveToPoint(int x, int y) {
            left = x * zoom - width / 2 + zoom / 2;
            top = y * zoom - height / 2 + zoom / 2;
            repaint();
        }
    }

    class LoupeStatus extends JPanel {
        private JLabel xLabel;
        private JLabel yLabel;
        private JLabel rLabel;
        private JLabel gLabel;
        private JLabel bLabel;
        private JLabel hLabel;
        private ScreenViewer.LoupeStatus.ColoredSquare square;
        private Color color;

        LoupeStatus() {
            setOpaque(true);
            setLayout(new GridBagLayout());
            setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));

            square = new ColoredSquare();
            add(square, new GridBagConstraints(0, 0, 1, 2, 0.0f, 0.0f,
                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
                    new Insets(0, 0, 0, 12), 0, 0 ));

            JLabel label;

            add(label = new JLabel("#ffffff"), new GridBagConstraints(0, 2, 1, 1, 0.0f, 0.0f,
                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
                    new Insets(0, 0, 0, 12), 0, 0 ));
            label.setForeground(Color.WHITE);
            hLabel = label;

            add(label = new JLabel("R:"), new GridBagConstraints(1, 0, 1, 1, 0.0f, 0.0f,
                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
                    new Insets(0, 6, 0, 6), 0, 0 ));
            label.setForeground(Color.WHITE);
            add(label = new JLabel("255"), new GridBagConstraints(2, 0, 1, 1, 0.0f, 0.0f,
                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
                    new Insets(0, 0, 0, 12), 0, 0 ));
            label.setForeground(Color.WHITE);
            rLabel = label;

            add(label = new JLabel("G:"), new GridBagConstraints(1, 1, 1, 1, 0.0f, 0.0f,
                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
                    new Insets(0, 6, 0, 6), 0, 0 ));
            label.setForeground(Color.WHITE);
            add(label = new JLabel("255"), new GridBagConstraints(2, 1, 1, 1, 0.0f, 0.0f,
                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
                    new Insets(0, 0, 0, 12), 0, 0 ));
            label.setForeground(Color.WHITE);
            gLabel = label;

            add(label = new JLabel("B:"), new GridBagConstraints(1, 2, 1, 1, 0.0f, 0.0f,
                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
                    new Insets(0, 6, 0, 6), 0, 0 ));
            label.setForeground(Color.WHITE);
            add(label = new JLabel("255"), new GridBagConstraints(2, 2, 1, 1, 0.0f, 0.0f,
                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
                    new Insets(0, 0, 0, 12), 0, 0 ));
            label.setForeground(Color.WHITE);
            bLabel = label;

            add(label = new JLabel("X:"), new GridBagConstraints(3, 0, 1, 1, 0.0f, 0.0f,
                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
                    new Insets(0, 6, 0, 6), 0, 0 ));
            label.setForeground(Color.WHITE);
            add(label = new JLabel("0 px"), new GridBagConstraints(4, 0, 1, 1, 0.0f, 0.0f,
                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
                    new Insets(0, 0, 0, 12), 0, 0 ));
            label.setForeground(Color.WHITE);
            xLabel = label;

            add(label = new JLabel("Y:"), new GridBagConstraints(3, 1, 1, 1, 0.0f, 0.0f,
                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
                    new Insets(0, 6, 0, 6), 0, 0 ));
            label.setForeground(Color.WHITE);
            add(label = new JLabel("0 px"), new GridBagConstraints(4, 1, 1, 1, 0.0f, 0.0f,
                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
                    new Insets(0, 0, 0, 12), 0, 0 ));
            label.setForeground(Color.WHITE);
            yLabel = label;

            add(Box.createHorizontalGlue(), new GridBagConstraints(5, 0, 1, 1, 1.0f, 0.0f,
                    GridBagConstraints.LINE_START, GridBagConstraints.BOTH,
                    new Insets(0, 0, 0, 0), 0, 0 ));
        }

        @Override
        protected void paintComponent(Graphics g) {
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, getWidth(), getHeight());
        }

        void showPixel(int x, int y) {
            xLabel.setText(x + " px");
            yLabel.setText(y + " px");

            int pixel = image.getRGB(x, y);
            color = new Color(pixel);
            hLabel.setText("#" + Integer.toHexString(pixel));
            rLabel.setText(String.valueOf((pixel >> 16) & 0xff));
            gLabel.setText(String.valueOf((pixel >>  8) & 0xff));
            bLabel.setText(String.valueOf((pixel      ) & 0xff));

            square.repaint();
        }

        private class ColoredSquare extends JComponent {
            @Override
            public Dimension getPreferredSize() {
                Dimension d = super.getPreferredSize();
                d.width = 60;
                d.height = 30;
                return d;
            }

            @Override
            protected void paintComponent(Graphics g) {
                g.setColor(color);
                g.fillRect(0, 0, getWidth(), getHeight());

                g.setColor(Color.WHITE);
                g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
            }
        }
    }

    class Crosshair extends JPanel {
        // magenta = 0xff5efe
        private final Color crosshairColor = new Color(0x00ffff);
        Point crosshair = new Point();
        private int width;
        private int height;
        private final ScreenshotViewer screenshotViewer;

        Crosshair(ScreenshotViewer screenshotViewer) {
            this.screenshotViewer = screenshotViewer;
            setOpaque(true);
            setLayout(new BorderLayout());
            add(screenshotViewer);
            addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent event) {
                    moveToPoint(event);
                }
            });
            addMouseMotionListener(new MouseMotionAdapter() {
                @Override
                public void mouseDragged(MouseEvent event) {
                    moveToPoint(event);
                }
            });
        }

        void moveToPoint(int x, int y) {
            crosshair.x = x;
            crosshair.y = y;
            status.showPixel(crosshair.x, crosshair.y);
            repaint();
        }

        private void moveToPoint(MouseEvent event) {
            crosshair.x = Math.max(0, Math.min(image.getWidth() - 1, event.getX()));
            crosshair.y = Math.max(0, Math.min(image.getHeight() - 1, event.getY()));
            loupe.moveToPoint(crosshair.x, crosshair.y);
            status.showPixel(crosshair.x, crosshair.y);

            repaint();
        }

        @Override
        public Dimension getPreferredSize() {
            return screenshotViewer.getPreferredSize();
        }

        @Override
        public Dimension getMaximumSize() {
            return screenshotViewer.getPreferredSize();
        }

        @Override
        public void paint(Graphics g) {
            super.paint(g);

            if (crosshair == null || width != getWidth() || height != getHeight()) {
                width = getWidth();
                height = getHeight();
                crosshair = new Point(width / 2, height / 2);
            }

            g.setColor(crosshairColor);

            g.drawLine(crosshair.x, 0, crosshair.x, height);
            g.drawLine(0, crosshair.y, width, crosshair.y);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, getWidth(), getHeight());
        }
    }

    class ScreenshotViewer extends JComponent {
        private final Color boundsColor = new Color(0xff5efe);

        ScreenshotViewer() {
            setOpaque(true);
        }

        @Override
        protected void paintComponent(Graphics g) {
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, getWidth(), getHeight());

            if (isLoading) {
                return;
            }

            if (image != null) {
                g.drawImage(image, 0, 0, null);
                if (overlay != null) {
                    Graphics2D g2 = (Graphics2D) g.create();
                    g2.setComposite(overlayAlpha);
                    g2.drawImage(overlay, 0, image.getHeight() - overlay.getHeight(), null);
                }
            }

            if (node != null) {
                Graphics s = g.create();
                s.setColor(boundsColor);
                ViewNode p = node.parent;
                while (p != null) {
                    s.translate(p.left - p.scrollX, p.top - p.scrollY);
                    p = p.parent;
                }
                s.drawRect(node.left, node.top, node.width - 1, node.height - 1);
                s.translate(node.left, node.top);

                s.setXORMode(Color.WHITE);
                if ((node.paddingBottom | node.paddingLeft |
                        node.paddingTop | node.paddingRight) != 0) {
                    s.setColor(Color.BLACK);
                    s.drawRect(node.paddingLeft, node.paddingTop,
                            node.width - node.paddingRight - node.paddingLeft - 1,
                            node.height - node.paddingBottom - node.paddingTop - 1);
                }
                if (node.hasMargins && (node.marginLeft | node.marginBottom |
                        node.marginRight | node.marginRight) != 0) {
                    s.setColor(Color.BLACK);
                    s.drawRect(-node.marginLeft, -node.marginTop,
                            node.marginLeft + node.width + node.marginRight - 1,
                            node.marginTop + node.height + node.marginBottom - 1);
                }

                s.dispose();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            if (image == null) {
                return new Dimension(320, 480);
            }
            return new Dimension(image.getWidth(), image.getHeight());
        }
    }

    private class CrosshairPanel extends JPanel {
        private final Color crosshairColor = new Color(0xff5efe);
        private final Insets insets = new Insets(0, 0, 0, 0);

        CrosshairPanel(LoupeViewer loupe) {
            setLayout(new BorderLayout());
            add(loupe);
        }

        @Override
        public void paint(Graphics g) {
            super.paint(g);

            g.setColor(crosshairColor);

            int width = getWidth();
            int height = getHeight();

            getInsets(insets);

            int x = (width - insets.left - insets.right) / 2;
            int y = (height - insets.top - insets.bottom) / 2;

            g.drawLine(insets.left + x, insets.top, insets.left + x, height - insets.bottom);
            g.drawLine(insets.left, insets.top + y, width - insets.right, insets.top + y);
        }

        @Override
        protected void paintComponent(Graphics g) {
            g.setColor(Color.BLACK);
            Insets insets = getInsets();
            g.fillRect(insets.left, insets.top, getWidth() - insets.left - insets.right,
                    getHeight() - insets.top - insets.bottom);
        }
    }

    public void actionPerformed(ActionEvent event) {
        if (task != null && !task.isDone()) {
            return;
        }
        task = new GetScreenshotTask();
        task.execute();
    }

    private class GetScreenshotTask extends SwingWorker<Boolean, Void> {
        private GetScreenshotTask() {
            workspace.beginTask();
        }

        @Override
        @WorkerThread
        protected Boolean doInBackground() throws Exception {
            RawImage rawImage;
            try {
                rawImage = device.getScreenshot();
            } catch (IOException ioe) {
                return false;
            }

            boolean resize = false;
            isLoading = true;
            try {
                if (rawImage != null) {
                    if (image == null || rawImage.width != image.getWidth() ||
                            rawImage.height != image.getHeight()) {
                        image = new BufferedImage(rawImage.width, rawImage.height,
                                BufferedImage.TYPE_INT_ARGB);
                        scanline = new int[rawImage.width];
                        resize = true;
                    }

                    switch (rawImage.bpp) {
                        case 16:
                            rawImage16toARGB(rawImage);
                            break;
                        case 32:
                            rawImage32toARGB(rawImage);
                            break;
                    }
                }
            } finally {
                isLoading = false;
            }

            return resize;
        }
        
        private int getMask(int length) {
            int res = 0;
            for (int i = 0 ; i < length ; i++) {
                res = (res << 1) + 1;
            }
    
            return res;
        }

        private void rawImage32toARGB(RawImage rawImage) {
            byte[] buffer = rawImage.data;
            int index = 0;

            final int redOffset = rawImage.red_offset;
            final int redLength = rawImage.red_length;
            final int redMask = getMask(redLength);
            final int greenOffset = rawImage.green_offset;
            final int greenLength = rawImage.green_length;
            final int greenMask = getMask(greenLength);
            final int blueOffset = rawImage.blue_offset;
            final int blueLength = rawImage.blue_length;
            final int blueMask = getMask(blueLength);
            final int alphaLength = rawImage.alpha_length;
            final int alphaOffset = rawImage.alpha_offset;
            final int alphaMask = getMask(alphaLength);

            for (int y = 0 ; y < rawImage.height ; y++) {
                for (int x = 0 ; x < rawImage.width ; x++) {
                    int value = buffer[index++] & 0x00FF;
                    value |= (buffer[index++] & 0x00FF) << 8;
                    value |= (buffer[index++] & 0x00FF) << 16;
                    value |= (buffer[index++] & 0x00FF) << 24;

                    int r = ((value >>> redOffset) & redMask) << (8 - redLength);
                    int g = ((value >>> greenOffset) & greenMask) << (8 - greenLength);
                    int b = ((value >>> blueOffset) & blueMask) << (8 - blueLength);
                    int a = 0xFF;

                    if (alphaLength != 0) {
                        a = ((value >>> alphaOffset) & alphaMask) << (8 - alphaLength);
                    }

                    scanline[x] = a << 24 | r << 16 | g << 8 | b;
                }

                image.setRGB(0, y, rawImage.width, 1, scanline,
                        0, rawImage.width);
            }
        }

        private void rawImage16toARGB(RawImage rawImage) {
            byte[] buffer = rawImage.data;
            int index = 0;

            for (int y = 0 ; y < rawImage.height ; y++) {
                for (int x = 0 ; x < rawImage.width ; x++) {
                    int value = buffer[index++] & 0x00FF;
                    value |= (buffer[index++] << 8) & 0x0FF00;

                    int r = ((value >> 11) & 0x01F) << 3;
                    int g = ((value >> 5) & 0x03F) << 2;
                    int b = ((value     ) & 0x01F) << 3;

                    scanline[x] = 0xFF << 24 | r << 16 | g << 8 | b;
                }

                image.setRGB(0, y, rawImage.width, 1, scanline,
                        0, rawImage.width);
            }
        }

        @Override
        protected void done() {
            workspace.endTask();
            try {
                if (get()) {
                    validate();
                    crosshair.crosshair = new Point(image.getWidth() / 2,
                            image.getHeight() / 2);
                    status.showPixel(image.getWidth() / 2, image.getHeight() / 2);
                    loupe.moveToPoint(image.getWidth() / 2, image.getHeight() / 2);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            repaint();
        }
    }

    private class OpenOverlayTask extends SwingWorker<BufferedImage, Void> {
        private File file;

        private OpenOverlayTask(File file) {
            this.file = file;
            workspace.beginTask();
        }

        @Override
        @WorkerThread
        protected BufferedImage doInBackground() {
            try {
                return IconLoader.toCompatibleImage(ImageIO.read(file));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            return null;
        }

        @Override
        protected void done() {
            try {
                overlay = get();
                repaint();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } finally {
                workspace.endTask();
            }
        }
    }
}
