
import * as en from "../enums.js"

/* From Server */
class ServerEvent {
	type: en.EventTypes;
	constructor(type: en.EventTypes = 0) {
		this.type = type;
	}
}

class EventAssignId extends ServerEvent {
	id: string;
	constructor(id: string) {
		super(en.EventTypes.assignId);
		this.id = id;
	}
}

class EventMatchmakingComplete extends ServerEvent {
	side: en.PlayerSide;
	constructor(side: en.PlayerSide) {
		super(en.EventTypes.matchmakingComplete);
		this.side = side;
	}
}

class EventGameUpdate extends ServerEvent {
	playerLeft = {
		y: 0
	};
	playerRight = {
		y: 0
	};
	ballsArr: {
		x: number,
		y: number,
		dirX: number,
		dirY: number,
		speed: number
	}[] = [];
	wallTop? = {
		y: 0
	};
	wallBottom? = {
		y: 0
	};
	lastInputId = 0;
	constructor() { // TODO: constructor that take GameComponentsServer maybe ?
		super(en.EventTypes.gameUpdate);
	}
}

class EventScoreUpdate extends ServerEvent {
	scoreLeft: number;
	scoreRight: number;
	constructor(scoreLeft: number, scoreRight: number) {
		super(en.EventTypes.scoreUpdate);
		this.scoreLeft = scoreLeft;
		this.scoreRight = scoreRight;
	}
}

class EventMatchEnd extends ServerEvent {
	winner: en.PlayerSide;
	constructor(winner: en.PlayerSide) {
		super(en.EventTypes.matchEnd);
		this.winner = winner;
	}
}


/* From Client */
class ClientEvent {
	type: en.EventTypes; // readonly ?
	constructor(type: en.EventTypes = 0) {
		this.type = type;
	}
}

class ClientAnnounce extends ClientEvent {
	role: en.ClientRole;
	clientId: string;
	matchOptions: en.MatchOptions;
	constructor(role: en.ClientRole, matchOptions: en.MatchOptions, clientId: string = "") {
		super(en.EventTypes.clientAnnounce);
		this.role = role;
		this.clientId = clientId;
		this.matchOptions = matchOptions;
	}
}

class EventInput extends ClientEvent {
	input: en.InputEnum;
	id: number;
	constructor(input: en.InputEnum = en.InputEnum.noInput, id: number = 0) {
		super(en.EventTypes.clientInput);
		this.input = input;
		this.id = id;
	}
}

export {
	ServerEvent, EventAssignId, EventMatchmakingComplete,
	EventGameUpdate, EventScoreUpdate, EventMatchEnd,
	ClientEvent, ClientAnnounce, EventInput
}
