package org.ntlab.radishforandroidstudio.cactusClient.models;


import java.util.HashMap;

import org.ntlab.radishforandroidstudio.framework.model3D.Position3D;
import org.ntlab.radishforandroidstudio.framework.model3D.Quaternion3D;

/**
 * インスタンスを管理するクラス
 *
 * @author r-isitani
 *
 */
public class Instances {
    private static Instances theInstance = null;
    private HashMap<String, Instance> instanceMap = new HashMap<>(); // instanceのIDと実体を管理
    private HashMap<String, Player> playerMap = new HashMap<>();

    private Instances() {
//		// ダミーコード
//		instanceMap.put("test1", new Instance("test1", 0));
//		instanceMap.put("test2", new Instance("test2", 1));
    }

    /**
     * Instancesクラスを取得する (シングルトン)
     *
     * @return
     */
    public static Instances getInstance() {
        if (theInstance == null) {
            theInstance = new Instances();
        }
        return theInstance;
    }

    public HashMap<String, Instance> createInstance(String name, int stageID) {
        String id = RandomStringGenerator.generateUniqueString(Instance.UNIQUE_ID_LENGTH,
                RandomStringGenerator.ALPHA_NUMERIC, instanceMap.keySet());
        Instance instance = new Instance(name, stageID);
        instanceMap.put(id, instance);
        HashMap<String, Instance> returnedMap = new HashMap<>();
        returnedMap.put(id, instance);
        return returnedMap;
    }

    public HashMap<String, Player> createPlayer(String instanceURI, String characterURI, CameraState cameraState,
                                                EmoteState.EmoteType animationClassToStart) {
        String id = RandomStringGenerator.generateUniqueString(Player.UNIQUE_ID_LENGTH,
                RandomStringGenerator.ALPHA_NUMERIC, playerMap.keySet());
        Player player = new Player(instanceURI, characterURI, cameraState, animationClassToStart);
        playerMap.put(id, player);
        HashMap<String, Player> returnedMap = new HashMap<>();
        returnedMap.put(id, player);
        return returnedMap;
    }

    public HashMap<String, Instance> getInstances() {
        return instanceMap;
    }

    public Instance getInstance(String instanceId) {
        return instanceMap.get(instanceId);
    }

    /**
     * 全playerを返す
     */
    public HashMap<String, Player> getPlayers() {
        return playerMap;
    }

    /**
     * IDに対応するinstanceにいる全playerを返す
     *
     * @param instanceId
     */
    public HashMap<String, Player> getPlayers(String instanceId) {
        if (instanceId == null || instanceId.isEmpty()) {
            return getPlayers();
        }
        HashMap<String, Player> responsePlayers = new HashMap<>();
        for (String id : playerMap.keySet()) {
            Player player = playerMap.get(id);
            String[] instanceURISplit = player.getInstanceID().split("/"); // …/instances/{instanceId}
            if (instanceId.equals(instanceURISplit[instanceURISplit.length - 1])) {
                responsePlayers.put(id, player);
            }
        }
        return responsePlayers;
    }

    public Player getPlayer(String playerId) {
        return playerMap.get(playerId);
    }

    public Instance updateInstance(String instanceId, Instance.State state) {
        Instance instance = instanceMap.get(instanceId);
        instance.update(state);
        return instance;
    }

    public Player updatePlayer(String playerId, String characterURI, Position3D position, Quaternion3D angle,
                               CameraState cameraState, EmoteState.EmoteType animationClassToStart) {
        Player player = playerMap.get(playerId);
        player.update(characterURI, position, angle, cameraState, animationClassToStart);
        return player;
    }

    public Instance destroyInstance(String instanceId) {
        return instanceMap.remove(instanceId);
    }

    public Player destroyPlayer(String playerId) {
        Player player = playerMap.get(playerId);
        player.destroy();
        return playerMap.remove(playerId);
    }
}