using Cryville.Common.Pdt;
using System;
using System.Collections.Generic;
using System.Reflection;

namespace Cryville.Crtr {
	public class SkinInterpreter : PdtInterpreter<PdtSkin> {
		public SkinInterpreter(string src, Binder binder) : base(src, binder) { }

		readonly List<SkinSelector> s = new List<SkinSelector>();
		readonly List<string> a = new List<string>();
		protected override object InterpretKey(Type type) {
			s.Clear(); a.Clear();
			string key = "";
			while (true) {
				int pp = Position;
				switch (cc) {
					case '@':
						GetChar();
						a.Add(GetIdentifier());
						break;
					case '$':
						GetChar();
						s.Add(new SkinSelector.CreateObject());
						key = null;
						break;
					case '.':
						GetChar();
						if (cc == '.') {
							GetChar();
							s.Add(new SkinSelector.State(GetIdentifier()));
							key = null;
						}
						else {
							var p3 = GetIdentifier();
							s.Add(new SkinSelector.Anchor(p3));
							if (key != null) key += "." + p3;
						}
						break;
					case '>':
						GetChar();
						s.Add(new SkinSelector.Property(GetExp()));
						break;
					case ';':
					case ':':
						return key;
					case '{':
						return new SkinSelectors(s, a);
					case '}':
						return null;
					case '*':
						GetChar();
						key += "*";
						break;
					default:
						var p4 = GetIdentifier();
						s.Add(new SkinSelector.ElementType(p4));
						if (key != null) key += p4;
						break;
				}
				ws();
				if (Position == pp) throw new FormatException("Invalid selector or key format");
			}
		}
	}
}
