// Path: MODSRC/vazkii/emotes/client/ClientProxy.java
// public class ClientProxy extends CommonProxy {
// 
// 	public static float time = 0F;
// 	public static float delta = 0F;
// 
// 	@Override
// 	public void init() {
// 		super.init();
// 		Tween.registerAccessor(ModelBiped.class, new ModelAccessor());
// 		FMLCommonHandler.instance().bus().register(this);
// 		
// 		initEmotes();
// 	}
// 	
// 	@Override
// 	public void handlePacket(PacketEmote message) {
// 		World world = Minecraft.getMinecraft().theWorld;
// 		EntityPlayer player = world.getPlayerEntityByName(message.playerName);
// 		if(player != null) {
// 			if(message.emoteName.equals("list"))
// 				player.addChatComponentMessage(EmoteHandler.buildEmoteListStr());
// 			else EmoteHandler.putEmote(player, message.emoteName);
// 		}
// 	}
// 	
// 	private void initEmotes() {
// 		EmoteHandler.emoteMap.put("airguitar", EmoteAirGuitar.class);
// 		EmoteHandler.emoteMap.put("balance", EmoteBalance.class);
// 		EmoteHandler.emoteMap.put("cheer", EmoteCheer.class);
// 		EmoteHandler.emoteMap.put("clap", EmoteClap.class);
// 		EmoteHandler.emoteMap.put("exorcist", EmoteExorcist.class);
// 		EmoteHandler.emoteMap.put("facepalm", EmoteFacepalm.class);
// 		EmoteHandler.emoteMap.put("gangnamstyle", EmoteGangnamStyle.class);
// 		EmoteHandler.emoteMap.put("headbang", EmoteHeadbang.class);
// 		EmoteHandler.emoteMap.put("levitate", EmoteLevitate.class);
// 		EmoteHandler.emoteMap.put("no", EmoteNo.class);
// 		EmoteHandler.emoteMap.put("point", EmotePoint.class);
// 		EmoteHandler.emoteMap.put("run", EmoteRun.class);
// 		EmoteHandler.emoteMap.put("salute", EmoteSalute.class);
// 		EmoteHandler.emoteMap.put("shaftheadtilt", EmoteShaftHeadTilt.class);
// 		EmoteHandler.emoteMap.put("shrug", EmoteShrug.class);
// 		EmoteHandler.emoteMap.put("stand", EmoteStand.class);
// 		EmoteHandler.emoteMap.put("think", EmoteThink.class);
// 		EmoteHandler.emoteMap.put("wave", EmoteWave.class);
// 		EmoteHandler.emoteMap.put("yes", EmoteYes.class);
// 		EmoteHandler.emoteMap.put("zombie", EmoteZombie.class);
// 	}
// 	
// 	@SubscribeEvent
// 	public void onRenderStart(RenderTickEvent event) {
// 		if(event.phase == Phase.START) {
// 			float ctime = (float) Math.floor(time) + event.renderTickTime;
// 			delta = (ctime - time) * 50;
// 			time = ctime;
// 			EmoteHandler.clearPlayerList();
// 		}
// 	}
// 	
// 	@SubscribeEvent
// 	public void onTick(ClientTickEvent event) {
// 		if(event.phase == Phase.START)
// 			time = (float) Math.ceil(time);
// 	}
// }


import net.minecraft.client.model.ModelBiped;
import net.minecraft.entity.player.EntityPlayer;
import vazkii.emotes.client.ClientProxy;
import aurelienribon.tweenengine.BaseTween;
import aurelienribon.tweenengine.Timeline;
import aurelienribon.tweenengine.TweenCallback;
import aurelienribon.tweenengine.TweenManager;
	
	private boolean done = false;
	
	public EmoteBase(EntityPlayer player, ModelBiped model, ModelBiped armorModel, ModelBiped armorLegsModel) {
		emoteManager = new TweenManager();
		state = new EmoteState(this);
		this.model = model;
		this.armorModel = armorModel;
		this.armorLegsModel = armorLegsModel;

		startTimeline(player, model, true);
		startTimeline(player, armorModel, false);
		startTimeline(player, armorLegsModel, false);
	}
	
	void startTimeline(EntityPlayer player, ModelBiped model, boolean callback) {
		Timeline timeline = getTimeline(player, model).start(emoteManager);
		if(callback)
			timeline.setCallback(new FinishCallback());
	}
	
	public abstract Timeline getTimeline(EntityPlayer player, ModelBiped model);
	
	public abstract boolean usesBodyPart(int part);
	
	public void update(boolean doUpdate) {
		state.load(model);
		state.load(armorModel);
		state.load(armorLegsModel);
		if(doUpdate) {
// Path: MODSRC/vazkii/emotes/client/ClientProxy.java
// public class ClientProxy extends CommonProxy {
// 
// 	public static float time = 0F;
// 	public static float delta = 0F;
// 
// 	@Override
// 	public void init() {
// 		super.init();
// 		Tween.registerAccessor(ModelBiped.class, new ModelAccessor());
// 		FMLCommonHandler.instance().bus().register(this);
// 		
// 		initEmotes();
// 	}
// 	
// 	@Override
// 	public void handlePacket(PacketEmote message) {
// 		World world = Minecraft.getMinecraft().theWorld;
// 		EntityPlayer player = world.getPlayerEntityByName(message.playerName);
// 		if(player != null) {
// 			if(message.emoteName.equals("list"))
// 				player.addChatComponentMessage(EmoteHandler.buildEmoteListStr());
// 			else EmoteHandler.putEmote(player, message.emoteName);
// 		}
// 	}
// 	
// 	private void initEmotes() {
// 		EmoteHandler.emoteMap.put("airguitar", EmoteAirGuitar.class);
// 		EmoteHandler.emoteMap.put("balance", EmoteBalance.class);
// 		EmoteHandler.emoteMap.put("cheer", EmoteCheer.class);
// 		EmoteHandler.emoteMap.put("clap", EmoteClap.class);
// 		EmoteHandler.emoteMap.put("exorcist", EmoteExorcist.class);
// 		EmoteHandler.emoteMap.put("facepalm", EmoteFacepalm.class);
// 		EmoteHandler.emoteMap.put("gangnamstyle", EmoteGangnamStyle.class);
// 		EmoteHandler.emoteMap.put("headbang", EmoteHeadbang.class);
// 		EmoteHandler.emoteMap.put("levitate", EmoteLevitate.class);
// 		EmoteHandler.emoteMap.put("no", EmoteNo.class);
// 		EmoteHandler.emoteMap.put("point", EmotePoint.class);
// 		EmoteHandler.emoteMap.put("run", EmoteRun.class);
// 		EmoteHandler.emoteMap.put("salute", EmoteSalute.class);
// 		EmoteHandler.emoteMap.put("shaftheadtilt", EmoteShaftHeadTilt.class);
// 		EmoteHandler.emoteMap.put("shrug", EmoteShrug.class);
// 		EmoteHandler.emoteMap.put("stand", EmoteStand.class);
// 		EmoteHandler.emoteMap.put("think", EmoteThink.class);
// 		EmoteHandler.emoteMap.put("wave", EmoteWave.class);
// 		EmoteHandler.emoteMap.put("yes", EmoteYes.class);
// 		EmoteHandler.emoteMap.put("zombie", EmoteZombie.class);
// 	}
// 	
// 	@SubscribeEvent
// 	public void onRenderStart(RenderTickEvent event) {
// 		if(event.phase == Phase.START) {
// 			float ctime = (float) Math.floor(time) + event.renderTickTime;
// 			delta = (ctime - time) * 50;
// 			time = ctime;
// 			EmoteHandler.clearPlayerList();
// 		}
// 	}
// 	
// 	@SubscribeEvent
// 	public void onTick(ClientTickEvent event) {
// 		if(event.phase == Phase.START)
// 			time = (float) Math.ceil(time);
// 	}
// }


// Path: MODSRC/vazkii/emotes/client/emote/base/EmoteBase.java
import net.minecraft.client.model.ModelBiped;
import net.minecraft.entity.player.EntityPlayer;
import vazkii.emotes.client.ClientProxy;
import aurelienribon.tweenengine.BaseTween;
import aurelienribon.tweenengine.Timeline;
import aurelienribon.tweenengine.TweenCallback;
import aurelienribon.tweenengine.TweenManager;

	
	private boolean done = false;
	
	public EmoteBase(EntityPlayer player, ModelBiped model, ModelBiped armorModel, ModelBiped armorLegsModel) {
		emoteManager = new TweenManager();
		state = new EmoteState(this);
		this.model = model;
		this.armorModel = armorModel;
		this.armorLegsModel = armorLegsModel;

		startTimeline(player, model, true);
		startTimeline(player, armorModel, false);
		startTimeline(player, armorLegsModel, false);
	}
	
	void startTimeline(EntityPlayer player, ModelBiped model, boolean callback) {
		Timeline timeline = getTimeline(player, model).start(emoteManager);
		if(callback)
			timeline.setCallback(new FinishCallback());
	}
	
	public abstract Timeline getTimeline(EntityPlayer player, ModelBiped model);
	
	public abstract boolean usesBodyPart(int part);
	
	public void update(boolean doUpdate) {
		state.load(model);
		state.load(armorModel);
		state.load(armorLegsModel);
		if(doUpdate) {
			emoteManager.update(ClientProxy.delta);