let Types = {
	Boolean: 0,
	Text: 1,
	Integer: 2,
	URL: 3,
	somethingelse: 4,
	Link: 5,
	Array: 6,
	View: 7,
	Object: 8,
	Real: 9,
	Float: 10,
	Modules: 11,
	Whatever: 12,
	Action: 13,
	Module: 14
}


class Type {
	constructor(type) {
		this.type = type;
	}

	getType() {
		return Object.keys(Types)[this.type];
	}

	parse(value) {
		return value;
	}
	resolve(value) {
		console.log("Called resolve on base super Type component");
		return true;
	}

	default(value) {
		this.defaultValue = value;
		return this;
	}

	require() {
		this.isRequired = true;
		return this;
	}
}

class Bool extends Type {
	constructor() {
		super(Types.Boolean);
	}

	resolve(value) {
		if((value !== undefined || this.isRequired) && value !== true && value !== false) 
			return false;
		return true;
	}

	parse(value) {
		return value === 'true' || value === "1" || value === 1 || value === true;
	}
}

class Action extends Type {
	constructor() {
		super(Types.Action);
	}

	resolve(value) {
		if(typeof value !== "object")
			return false;
		if(typeof value.type !== "string") 
			return false;
		return true;
	}

	parse(value) {
		if(!value) return { _Action: {empty: true}};
		let {
			type,
			data
		} = value;

		return {
			_Action: {initial: value},
			type,
			data
		};
	}
}

class Text extends Type {
	constructor() {
		super(Types.Text);
	}

	color() {
		this.isColor = true;
		return this;
	}

	resolve(value) {
		if(typeof value === "string")
			return true;
		else if ((value === undefined || value === null) && !this.isRequired)
			return true

		return true;
	}
}


class Integer extends Type {
	constructor() {
		super(Types.Integer);
	}

	parse(value) {
		try{
			return parseInt(value);
		}catch(e) {
			return this.defaultValue || 0;
		}
	}

	resolve(value) {
		if (typeof value === "number" && parseInt(value) === value)
			return true;
		else if ((value === undefined || value === null) && !this.isRequired)
			return true;
		return false;
	}
}

class Real extends Type {
	constructor() {
		super(Types.Real);
	}

	parse(value) {
		try{
			return parseFloat(value);
		}catch(e) {
			return this.defaultValue || 0;
		}
	}

	resolve(value) {
		if (typeof value === "number" && parseFloat(value) === value)
			return true;
		else if ((value === undefined || value === null) && !this.isRequired)
			return true;
		return false;
	}
}
class JSObject extends Type {
	constructor() {
		super(Types.Object);
	}

	resolve(value) {
		if (typeof value === "object")
			return true;
		else if ((value === undefined || value === null) && !this.isRequired)
			return true;
		return false;
	}
}


class JSArray extends Type{
	constructor(Template){
		super(Types.Array);
		this.Template = Template;
	}
	resolve(value){
		if(Array.isArray(value)) {
			for(var i=0;i<value.length;i++) {
				if(!this.Template.resolve(value[i])) {
					return false;
				}
			}
			return true;
		} else if ((value === undefined || value === null) && !this.isRequired)
			return true;
		return false;
	}
}


class Module extends Type{
	constructor(){
		super(Types.Module)
	}

	parse(data) {

		let {
			value,
			namespace
		} = data || {};
		return {
			value,
			namespace
		};
	}

	resolve(value){
		if(typeof value === "object" && value.value)
			return true;
		else if ((value === undefined || value === null) && !this.isRequired)
			return true;
		return false;
	}
}

export default {
	Action,
	Bool,
	Real,
	Object: JSObject,
	Integer,
	Text,
	Types,
	Type,
	Module,
	Array: JSArray
}






// export function Resolver (input, value) {
// 	const msg = "Resolver cannot parse Input Field";
// 	switch (input.type) {
// 		case Types.Object: 
// 			input.value = value || input.value || {};
// 			break;
// 		case Types.Boolean:
// 			if(value !== undefined && value !== null) {
// 				input.value = !!value;
// 			}
// 			break;
// 		case Types.Number:
// 			try {
// 				input.value = parseInt(value === undefined || value === null ? input.value : value);
// 			} catch (e) {
// 				Logger.warning(msg, { inputField: input });
// 			}
// 			break;
// 		case Types.Real:
// 			try {
// 				input.value = parseFloat(value === undefined || value === null ? input.value : value);
// 			} catch (e) {
// 				Logger.warning(msg, { inputField: input });
// 			}
// 			break;
// 		case Types.Text:
// 			if(value !== undefined && value !== null) {
// 				input.value = value;
// 			}
// 			break;
// 		case Types.Array:
// 				if (!Array.isArray(value)) {
// 					try {
// 						if(typeof value === "string") {
// 							input.value = JSON.parse(value);
// 						}
// 					} catch (e) {
// 						Logger.warning(msg, { inputField: input });
// 					}
// 				} else {
// 					input.value = value;
// 				}
// 				break;
// 		default: 
// 			input.value = value;
// 			break;

// 	}
// 	return input.value;
// }

export function Resolver (Inputs, props) {
	const msg = "Resolver cannot parse Input Field";

	let structure = {};
	for(var i in Inputs) {
		let field = Inputs[i];
		let parseVal = (props[i] === undefined) ? field.defaultValue : props[i];
		let value = field.parse(parseVal);
		if(field.resolve(value)){
			structure[i] = value;
			// console.log(value);
		} else {
			// console.log(`Field ${i} failed to resolve to ${field.getType()}`);
		}
	}
	return structure;
}