/*
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 server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import common.CommonUtils;

public class Config {

    private static Map<Integer,Race> races = new HashMap<Integer,Race>();
    private static Map<Integer,Klass> klasses = new HashMap<Integer,Klass>();
    private static String[] stats = {};
    
    private Config() {
        /* disable default constructor */
    }
    
    public static boolean addStat(String stat) {
        Set<String> newStats = new TreeSet<String>();
        newStats.addAll(Arrays.asList(stats));
        if (newStats.add(stat)) {
            stats = newStats.toArray(new String[] {});
            for (Player p : IdType.getAllPlayers()) {
                p.recalcStats();
            }
            return true;
        }
        else {
            return false; // already exists
        }
    }
    
    public static boolean removeStat(String stat) {
        Set<String> newStats = new TreeSet<String>();
        newStats.addAll(Arrays.asList(stats));
        if (newStats.remove(stat)) {
            stats = newStats.toArray(new String[] {});
            for (Race race : races.values()) {
                race.removeStat(stat);
            }
            for (Klass klass : klasses.values()) {
                klass.removeStat(stat);
            }
            for (Player p : IdType.getAllPlayers()) {
                p.recalcStats();
            }
            return true;
        }
        else {
            return false; // stat does not exist
        }
    }
    
    public static String[] getStats() {
        return stats;
    }
    
    public static Collection<Klass> getKlasses() {
        return Collections.unmodifiableCollection(klasses.values());
    }
    
    public static Klass getKlass(int id) {
        return klasses.get(id);
    }
    
    public static Klass createKlass(String name) {
        Klass klass = new Klass(name);
        klasses.put(klass.getId(), klass);
        return klass;
    }
    
    public static boolean deleteKlass(int id) {
        return klasses.remove(id) != null;
    }
    
    public static Klass getUnknownKlass() {
        Klass klass = Config.getKlass(0);
        if (klass == null) {
            klass = new Klass("Unknown");
            klass.id = 0;
            klasses.put(0, klass);
        }
        return klass;
    }

    public static Collection<Race> getRaces() {
        return Collections.unmodifiableCollection(races.values());
    }
    
    public static Race getRace(int id) {
        return races.get(id);
    }
    
    public static Race createRace(String name) {
        Race race = new Race(name);
        races.put(race.getId(), race);
        return race;
    }
    
    public static boolean deleteRace(int id) {
        return races.remove(id) != null;
    }
    
    public static Race getUnknownRace() {
        Race race = Config.getRace(0);
        if (race == null) {
            race = new Race("Unknown");
            race.id = 0;
            races.put(0, race);
        }
        return race;
    }
    
    public static void doSave(ObjectOutputStream oos) throws IOException {
        oos.writeInt(4); // protocol version
        oos.writeObject(stats);
        oos.writeObject(races);
        oos.writeObject(klasses);
    }
    
    public static void doLoad(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        int version = ois.readInt(); // protocol version
        stats = (String[]) ois.readObject();
        if (version >= 3) {
            races = CommonUtils.uncheckedCast(ois.readObject());
        }
        else {
            Map<String,Race> map = CommonUtils.uncheckedCast(ois.readObject());
            for (Race race : map.values()) {
                races.put(race.getId(), race);
            }
        }
        if (version >= 4) {
            klasses = CommonUtils.uncheckedCast(ois.readObject());
        }
        else if (version >= 2) {
            Map<String,Klass> map = CommonUtils.uncheckedCast(ois.readObject());
            for (Klass klass : map.values()) {
                klasses.put(klass.getId(), klass);
            }
        }
    }

}