/*
Copyright (C) 2005 David Green <green@couchpotato.net>
All Rights Reserved.

This file is part of Aelfengard.

Aelfengard is proprietary software. You may not redistribute it without
prior written permission from the copyright holder.
*/

package common.ui;

import java.awt.Dimension;
import java.awt.MediaTracker;
import java.awt.Window;
import java.util.HashMap;
import java.util.Map;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

/**
 * Miscellanous utilities for use by the client software.
 * 
 * @author David Green <green@couchpotato.net>
 */
public class ClientUtils {

    /**
     * Given a window and a screen width/height percentage,
     * this method will set the size to that percentage of
     * the screen, and set the "setLocationByPlatform" flag
     * to true.
     * 
     * @param window the window to resize
     * @param xpct the percentage of the screen width
     * @param ypct the percentage of the screen height
     */
    public static void initWindow(Window window, double xpct, double ypct) {
        Dimension ss = window.getToolkit().getScreenSize();
        window.setSize((int) (ss.getWidth() * xpct), (int) (ss.getHeight() * ypct));
        window.setLocationByPlatform(true);
    }
    
    
    /**
     * Place a new object into the map before loading an image from the net.
     * When done loading the image, if your "lock" object is still in place,
     * then actually update the JLabel with the new image. Otherwise, just
     * do nothing.
     */
    private static final Map<JLabel,Object> imageLocks = new HashMap<JLabel,Object>();

    /**
     * Sets the specified label's image to the specified image filename.
     * This method won't actually block. It will start a new thread to
     * actually load the image. When the load is complete, or an error
     * occurs, the runnable will be run in case you have any followup
     * logic after updating the image (such as removing a loading
     * animation)
     * 
     * @param label the label whose image property should be set
     * @param filename the filename of the image (relative path under /graphics/)
     * @param runnable the runnable to run after the image load is complete/errored
     */
    public static void setImage(final JLabel label, final String filename, final Runnable runnable) {
        if (filename == null) {
            label.setText("");
            label.setIcon(null);
            if (runnable != null) {
                runnable.run();
            }
            return;
        }
        final Object lock = new Object();
        imageLocks.put(label, lock);
        new Thread() {
            @Override
            public void run() {
                final ImageIcon icon = GameClient.getImageIcon("graphics/" + filename);
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        try {
                            Object newLock = imageLocks.get(label);
                            if (newLock != lock) {
                                return; // we're outdated already
                            }
                            imageLocks.remove(label); // remove our lock
                            if (icon.getImageLoadStatus() == MediaTracker.COMPLETE) {
                                label.setText("");
                                label.setIcon(icon);
                                if (label.getParent() != null && 
                                        label.getParent().getLayout() == null) {
                                    label.setSize(label.getPreferredSize());
                                }
                            } else {
                                label.setText("Couldn't load image.");
                                label.setIcon(null);
                            }
                        }
                        finally {
                            if (runnable != null) {
                                runnable.run();
                            }
                        }
                    }
                });
            }
        }.start();
    }

}