using System.Collections;
using Newtonsoft.Json.Linq;
using System.IO;
using Newtonsoft.Json;
using UnityEngine;

public abstract class Module {
	private string name;
	private string uniqueName;
	private float health;
	private float resistance;
	protected Sprite sprite;

	protected Module(JObject json) {
		name = (string)json["name"];
		uniqueName = (string)json["uniqueName"];
		health = (float)json["hitPoints"];
		resistance = (float)json["resistance"];
	}

	public static JObject jsonFromFile(string jsonPath) {
		StreamReader reader = File.OpenText(jsonPath);
		return (JObject)JToken.ReadFrom(new JsonTextReader(reader));
	}

	public string getName() {
		return name;
	}

	public string getUniqueName() {
		return uniqueName;
	}

	public float getHealth() {
		return health;
	}

	public float getResistance() {
		return resistance;
	}

	public Sprite getSprite() {
		return sprite;
	}

	virtual public bool canBeDisabled() {
		return true;
	}

	public abstract void updateClasses();
	public abstract ModuleData getData(int parent);
}

public abstract class ModuleData {
	protected float health;
	protected int parent;
	protected int id;
	protected Module template;
	protected bool wasFiring;
	protected bool firing;
	private bool disabled;

	public ModuleData(int parent, Module template) {
		this.parent = parent;
		this.id = Util.freshId();
		this.template = template;
		this.health = template.getHealth();

		GameController.addModuleData(this);
	}

	public int getID() {
		return id;
	}

	public int getParent() {
		return parent;
	}

	public float getHealth() {
		return health;
	}

	public void addDamage(float amount) {
		if (health == 0.0f) {
			return;
		}

		Requests.setHealth(GameController.fromID(parent), id, Mathf.Max(0.0f, health - amount * template.getResistance()));
	}

	public void setHealth(float newHealth) {
		health = newHealth;
	}

	virtual public void updateTime(float delta) {
	}

	virtual public bool isFiring() {
		if (NetworkManager.isServer()) {
			return false;
		}
		else {
			return firing;
		}
	}

	public bool isDestroyed() {
		return health == 0.0f;
	}

	public bool isDisabled() {
		return disabled;
	}

	public bool isOperationnal() {
		return !isDestroyed() && !isDisabled();
	}

	//only called by server to send state updates to the clients
	public void updateState() {
		if (wasFiring != isFiring()) {
			Requests.setIsFiring(GameController.fromID(parent), id, isFiring());
			wasFiring = isFiring();
		}
	}

	//only used by clients
	public void setFiring(bool value) {
		firing = value;
	}

	public void setDisabled(bool value) {
		disabled = value;
	}

	public abstract void deployUnit(int storedUnitID);
}