/// <reference path="../../../_system/_shared/Initializing.ts"/>

const enum moodletTimeMode{
	Continuous,
	Resetting,
	Lasting
}

const enum moodletAccumulationMode{
	ADD,
	HIGHEST,
	LOWEST,
	DIMINISHING,
	DIMINISHING_REVERSE
}




class Moodlet extends Initializing{
	id:string;
	title:string='Title Missing';
	groupId:string= 'none';
	description:string= 'Description Missing';
	effect:number=0;
	timeConversion:number=0;
	timeMode:moodletTimeMode= moodletTimeMode.Resetting;
	duration:number=60;
	maxDuration:number=0;
	includes:Array<string>=[];

	static get(moodletId:string):Moodlet{
		let result = setup.moodlets[moodletId] ?? new NullMoodlet();
		result.id = moodletId;
		return result;
	}

	

	constructor(initialData:object={}){
		super();
		this.init(initialData);
	}

	clone(){
		return new Moodlet();
	}	
}

setup.Moodlet = Moodlet;

class ActiveMoodlet extends Moodlet{

	//expiration:Date;
	private dynamicDataReference;

	static create(moodletId:string,dynamicData:object):ActiveMoodlet{
		let staticMoodlet = Moodlet.get(moodletId) as ActiveMoodlet;
		let dynamicMoodlet = new ActiveMoodlet(staticMoodlet);
		dynamicMoodlet.dynamicDataReference = dynamicData;
		return dynamicMoodlet;
	}

	get expiration():Date{
		return this.dynamicDataReference?.expiration ?? new Date(0);
	}

	get isActive():boolean{
		if(!this.dynamicDataReference)
			return false;
		const time = State.variables.time;
		return time.isFuture(this.expiration);
	}
}

class PainMoodlet extends ActiveMoodlet{
	static createPainMoodlet(pain:number):ActiveMoodlet{
		if(pain <= 0)
			return new NullMoodlet();
		let result = new PainMoodlet(Moodlet.get('pain'));
		result.effect = Math.round(pain * -1);
		return result;
	}

	get expiration():Date{
		return State.variables.time.endTime;
	}

	get isActive():boolean{
		return (this.effect != 0);
	}
}

class NullMoodlet extends ActiveMoodlet{
	get isActive(){
		return false;
	}
}

class MoodletGroup extends Initializing{

	id:string;
	accumulationMode: moodletAccumulationMode;
	diminishFactor:0;

	static get(moodletGroupId:string):MoodletGroup{
		let result = setup.moodletGroups[moodletGroupId] ?? new NullMoodletGroup();
		result.id = moodletGroupId;
		return result;
	}

	constructor(initialData:object={}){
		super(initialData);
	}
}

setup.MoodletGroup = MoodletGroup;

class NullMoodletGroup extends MoodletGroup{

}

setup.moodlets ??= {};
setup.moodletGroups ??= {};

setup.moodletGroups.none = new MoodletGroup({
	accumulationMode: moodletAccumulationMode.ADD
});

setup.moodletGroups.pain = new MoodletGroup({
	accumulationMode: moodletAccumulationMode.LOWEST
});