package com.github.niwaniwa.we.core.player;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

import com.github.niwaniwa.we.core.WhiteEggCore;

/**
 * WhitePlayerのfactoryクラス
 * @author niwaniwa
 *
 */
public class WhitePlayerFactory {

	/**
	 * instance化不可
	 */
	private WhitePlayerFactory(){}

	private static final List<WhitePlayer> players = new ArrayList<>();

	/**
	 * プレイヤーのインスタンスを返します
	 * @param player プレイヤー
	 * @return プレイヤー
	 */
	public static WhitePlayer newInstance(Player player){
		for(WhitePlayer p : players){
			if(p.getUniqueId().equals(player.getUniqueId())){ return p; }
		}
		WhitePlayer white = new WhiteEggPlayer(player);
		white.load();
		players.add(white);
		return white;
	}

	/**
	 * instance
	 * @param <T> WhitePlayerを継承したクラス
	 * @param clazz 取得するクラス
	 * @param player プレイヤー
	 * @return WhitePlayer 指定したクラスのinstance
	 * @deprecated エラーが起こる可能性が高いので使わないでください
	 */
	public static <T extends WhitePlayer> WhitePlayer newInstance(Class<T> clazz, Player player){
		if(clazz.isInterface()){ return null; }
		if(Modifier.isAbstract(clazz.getModifiers())){ return null; }
		T instance = null;
		try {
			Constructor<T> c = clazz.getConstructor(Player.class);
			instance = c.newInstance(player);
		} catch (NoSuchMethodException | SecurityException | InstantiationException |
				IllegalAccessException | IllegalArgumentException | InvocationTargetException e){
		}
		if(instance == null){ return null; }
		instance.load();
		return instance;
	}

	/**
	 * 型を指定したクラスへ変換する
	 * @param <T> WhitePlayerを継承したクラス
	 * @param from 変換前のinstance
	 * @param to 変換後のクラス
	 * @return 指定したクラスのinstance(データ引き継ぎ)
	 * @deprecated
	 */
	public static <T extends WhitePlayer> WhitePlayer cast(WhitePlayer from, Class<T> to){
		if(Modifier.isAbstract(to.getModifiers())
				|| from.getClass().getSimpleName().equals(to.getSimpleName())){
			return null;
		}
		from.save();
		WhitePlayer instance = null;
		try {
			Constructor<?> constructor = to.getConstructor(Player.class);
			instance = (WhitePlayer) (constructor == null ? to.getConstructor(WhitePlayer.class).newInstance(from) : constructor.newInstance(from.getPlayer()));
		} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
				| NoSuchMethodException | SecurityException e) {
		}
		instance.saveVariable(from.serialize().toString());
		return instance;
	}

	/**
	 * プレイヤーデータの保存
	 */
	public static void saveAll(){
		System.out.println("Saving players (WhiteEgg)");
		for(WhitePlayer p : WhitePlayerFactory.getPlayers()){
			p.save();
		}
	}

	/**
	 * プレイヤーデータの読み込み
	 */
	public static void load(){
		if(Bukkit.getOnlinePlayers().size() == 0){ return; }
		for(WhitePlayer p : WhiteEggCore.getAPI().getOnlinePlayers()){
			p.reload();
		}
	}

	/**
	 * サーバー起動時から取得時までに生成されたプレイヤーのインスタンスの取得
	 * @return instance
	 */
	public static List<WhitePlayer> getPlayers(){
		return players;
	}

}

@@ -1031,49 +1031,8 @@
 nce%0A
-%09 * @deprecated %E3%82%A8%E3%83%A9%E3%83%BC%E3%81%8C%E8%B5%B7%E3%81%93%E3%82%8B%E5%8F%AF%E8%83%BD%E6%80%A7%E3%81%8C%E9%AB%98%E3%81%84%E3%81%AE%E3%81%A7%E4%BD%BF%E3%82%8F%E3%81%AA%E3%81%84%E3%81%A7%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%0A
 %09 */
@@ -1071,27 +1071,17 @@
 Player%3E 
-WhitePlayer
+T
  newInst
@@ -1089,37 +1089,37 @@
 nce(
-Class%3CT%3E clazz, Player player
+Player player, Class%3CT%3E clazz
 )%7B%0A%09
@@ -1763,24 +1763,56 @@
 ecated%0A%09 */%0A
+%09@SuppressWarnings(%22unchecked%22)%0A
 %09public stat
@@ -1838,27 +1838,17 @@
 Player%3E 
-WhitePlayer
+T
  cast(Wh
@@ -2026,27 +2026,17 @@
 ve();%0A%09%09
-WhitePlayer
+T
  instanc
@@ -2133,27 +2133,17 @@
 ance = (
-WhitePlayer
+T
 ) (const

Change a return value of newInstance of WhitePlayerFactory