/*
 *  Copyright 2002-2009 Mikhail Kryshen <mikhail@kryshen.net>
 *
 *  This file is part of BMTron.
 *
 *  BMTron is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  BMTron is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with BMTron.  If not, see <http://www.gnu.org/licenses/>.
 */

package kryshen.bmtron;

import java.awt.Color;
import java.awt.Font;
import java.awt.Image;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import kryshen.util.ResourceLoader;

public class Skin {
    private static final byte[] MAGIC = "(BM Resources)".getBytes();
    private static final String NAME = "BMTron Skin 1.3";
    
    public static final int DATA_INT = 4;
    public static final int DATA_IMAGE = 8;
    public static final int DATA_COLOR = 9;
    public static final int DATA_FONT = 10;
    
    private URL source;
    private boolean loaded = false;
    
    final int effectWidth = 50;
    final int effectHeight = 50;
    
    Image background = null;
    Image title = null;
    Image activeTitle = null;
    Image field = null;
    Image settings = null;
    Image yes = null;
    Image no = null;
    Image start = null;
    Image teamplay = null;
    Image explosion = null;
    Image appearUp = null;
    Image appearDown = null;
    Image[] controls = new Image[7];
    Image[] snake = new Image[10];
            
    Color backColor = Color.white;
    Color statusTextColor = Color.blue;
    Color messageTextColor1 = Color.blue;
    Color messageTextColor2 = Color.red;
    Color messageBackColor = Color.white;
    Color messageShadowColor = Color.black;
    Color messageBorderColor = Color.red;
    Color linkColor = Color.blue;
    Color buttonBorderColor = Color.blue;
    Color activeButtonBorderColor = Color.red;
    Color buttonBackColor = Color.white;
    Color buttonTextColor = Color.blue;
    Color activePanelBorderColor = Color.white;
    
    Font statusFont = new Font("Helvetica", Font.BOLD, 12);
    Font messageFont1 = new Font("Helvetica", Font.BOLD, 32);
    Font messageFont2 = new Font("Helvetica", Font.BOLD, 16);
    Font linkFont = new Font("Helvetica", Font.PLAIN, 12);
    Font buttonFont = new Font("Helvetiva", Font.BOLD, 14);
    
    private final Game game;
    
    public Skin(Game game, URL source) {
        this.game = game;
        this.source = source;
    }
    
    public Object getSkinLock() {
        return this;
    }
    
    public void load() throws IOException, InterruptedException {
        InputStream in = source.openStream();
        ResourceLoader loader = new ResourceLoader(game, NAME, in);
        int progress;
        
        do {
            progress = loader.loadNext();
            game.setStatus((progress * 100 / 0xFF) + "% loaded");
            
            switch (loader.getResourceType()) {
                case ResourceLoader.DATA_IMAGE:
                    setImage(loader.getResourceName(), loader.getImage());
                    break;
                case ResourceLoader.DATA_COLOR:
                    setColor(loader.getResourceName(), loader.getColor());
                    break;
                case ResourceLoader.DATA_FONT:
                    setFont(loader.getResourceName(), loader.getFont());
                    break;
            }
            
        } while (progress != 0xFF);
        
        in.close();
        loaded = true;
    }
    
    public boolean isLoaded() {
        return loaded;
    }
    
    private void setFont(String name, Font font) {
        synchronized (getSkinLock()) {
            if (name.equals("status"))
                statusFont = font;
            else if (name.equals("message1"))
                messageFont1 = font;
            else if (name.equals("message2"))
                messageFont2 = font;
            else if (name.equals("link"))
                linkFont = font;
            else if (name.equals("button"))
                buttonFont = font;
            else return;
        }
        
        game.repaint();
    }
    
    private void setImage(String name, Image image) {
        synchronized (getSkinLock()) {
            if (name.equals("background"))
                background = image;
            else if (name.equals("title"))
                title = image;
            else if (name.equals("active_title"))
                activeTitle = image;
            else if (name.equals("field"))
                field = image;
            else if (name.equals("settings"))
                settings = image;
            else if (name.equals("yes"))
                yes = image;
            else if (name.equals("no"))
                no = image;
            else if (name.equals("start"))
                start = image;
            else if (name.equals("teamplay"))
                teamplay = image;
            else if (name.equals("explosion"))
                explosion = image;
            else if (name.equals("appear_up"))
                appearUp = image;
            else if (name.equals("appear_down"))
                appearDown = image;
            else if (name.startsWith("control")) {
                int index = Integer.parseInt(name.substring(7));
                if (index < controls.length) controls[index] = image;
            } else if (name.startsWith("snake")) {
                int index = Integer.parseInt(name.substring(5));
                if (index < snake.length) snake[index] = image;
            } else return;
        }
        
        game.repaint();
    }
    
    private void setColor(String name, Color color) {
        synchronized (getSkinLock()) {
            if (name.equals("background"))
                backColor = color;
            else if (name.equals("status_text"))
                statusTextColor = color;
            else if (name.equals("message_text1"))
                messageTextColor1 = color;
            else if (name.equals("message_text2"))
                messageTextColor2 = color;
            else if (name.equals("message_shadow"))
                messageShadowColor = color;
            else if (name.equals("message_border"))
                messageBorderColor = color;
            else if (name.equals("link"))
                linkColor = color;
            else if (name.equals("button_border"))
                buttonBorderColor = color;
            else if (name.equals("active_button_border"))
                activeButtonBorderColor = color;
            else if (name.equals("button_text"))
                buttonTextColor = color;
            else if (name.equals("button_background"))
                buttonBackColor = color;
            else if (name.equals("active_panel_border"))
                activePanelBorderColor = color;
            else if (name.equals("message_background")) {
                try {
                    messageBackColor = new Color(color.getRed(),
                            color.getGreen(), color.getBlue(), 210);
                } catch (IncompatibleClassChangeError e) {
                    messageBackColor = color;
                }
            } else return;
        }
        
        game.repaint();
    }
    
    public String toString() {
        return getClass().getName() + "[" + source + "]";
    }
}
