using Cryville.Common;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;

namespace Cryville.Crtr.Browsing {
	public abstract class ResourceConverter {
		public abstract string[] GetSupportedFormats();
		public abstract IEnumerable<Resource> ConvertFrom(FileInfo file);
	}
	public abstract class Resource {
		protected Resource(string name) {
			Name = StringUtils.EscapeFileName(name);
		}
		public string Name { get; private set; }
		public abstract bool Valid { get; }
		public override string ToString() {
			return string.Format("{0} ({1})", Name, ReflectionHelper.GetSimpleName(GetType()));
		}
	}
	public class RawChartResource : Resource {
		public RawChartResource(string name, Chart main, ChartMeta meta) : base(name) {
			Main = main; Meta = meta;
		}
		public Chart Main { get; private set; }
		public ChartMeta Meta { get; private set; }
		public override bool Valid { get { return true; } }
	}
	public abstract class FileResource : Resource {
		public FileResource(string name, FileInfo master) : base(name) {
			Master = master;
			Attachments = new List<FileInfo>();
		}
		public FileInfo Master { get; private set; }
		public List<FileInfo> Attachments { get; private set; }
		public override bool Valid {
			get {
				if (!Master.Exists) return false;
				foreach (var file in Attachments) {
					if (!file.Exists) return false;
				}
				return true;
			}
		}
	}
	public class ChartResource : FileResource {
		public ChartResource(string name, FileInfo master) : base(name, master) {
			using (var reader = new StreamReader(master.FullName)) {
				var meta = JsonConvert.DeserializeObject<ChartMeta>(reader.ReadToEnd());
				Attachments.Add(new FileInfo(Path.Combine(master.Directory.FullName, meta.data + ".json")));
				if (meta.cover != null) Attachments.Add(new FileInfo(Path.Combine(master.Directory.FullName, meta.cover)));
			}
		}
	}
	public class SongResource : FileResource {
		public SongResource(string name, FileInfo master) : base(name, master) { }
	}
	public class RulesetResource : FileResource {
		public RulesetResource(string name, FileInfo master) : base(name, master) {
			using (var reader = new StreamReader(master.FullName)) {
				var meta = JsonConvert.DeserializeObject<Ruleset>(reader.ReadToEnd());
				Attachments.Add(new FileInfo(Path.Combine(master.Directory.FullName, meta.data + ".pdt")));
			}
		}
	}
	public class SkinResource : FileResource {
		public string RulesetName { get; private set; }
		public SkinResource(string name, FileInfo master) : base(name, master) {
			using (var reader = new StreamReader(master.FullName)) {
				var meta = JsonConvert.DeserializeObject<Skin>(reader.ReadToEnd());
				RulesetName = meta.ruleset;
				Attachments.Add(new FileInfo(Path.Combine(master.Directory.FullName, meta.data + ".pdt")));
				foreach (var frame in meta.frames) {
					Attachments.Add(new FileInfo(Path.Combine(master.Directory.FullName, frame)));
				}
			}
		}
	}
}