include(Resources.idRelative("mtr:lib/harrys_lib.js"));
include("display.js");
include("dyntextnumber.js");

var rawModels = ModelManager.loadPartedRawModel(Resources.manager(), Resources.idRelative("mtr:71-605_scripted/ktm.obj"), null);
var models = uploadPartedModels(rawModels, true, true);

var rawModels2 = ModelManager.loadPartedRawModel(Resources.manager(), Resources.idRelative("mtr:71-605_scripted/bogie.obj"), null);
var bogieModel = uploadPartedModels(rawModels2, true, true);

var doorCoef = 1.1194

var shouldRenderWindows = true;

function create(ctx, state, train) {
	displCreate(ctx, state, train);
	dtnumCreate(train, state);

	initWipers(state);
	initRocking(train, state);
	initWheelAngle(state);

	state.postCreateFunctionCalled = false;

	state.hasGraf = false;

	state.grafTypes = [];
	state.grafShouldBeArray = [];

	state.number = (1000 + Math.abs(train.id() % 1000))
	state.postCreateFunctionCalled = false;


}


function dispose(ctx, state, train) {
	displDispose(ctx, state, train);
	dtnumDispose(train, state)
}

function render(ctx, state, train) {
	setPostcreateInfo(ctx, state, train); // train.siding() при вызове в функции create возвращает null, поэтому нужна доп. проверка.
	updateLogic(state, train);
	renderLogic(ctx, state, train);
	displRender(ctx, state, train);
	dtnumRender(train, state);
}



function setPostcreateInfo(ctx, state, train) {
	if (train.siding() == null || state.postCreateFunctionCalled) {
		return;
	}
	let num = (Math.abs(parseInt(train.siding().name)) % 10000);

	state.number = isNaN(num) ? state.number : num;
	state.postCreateFunctionCalled = true;

}

function updateLogic(state, train) {
	updateRocking(train, state, 50, 50, 70, 70);
	updateWipers(train, state);
	updateWheelAngle(train, state);

}



function renderLogic(ctx, state, train) {
	let matrices = new Matrices();
	renderHead(ctx, state, train, 0, matrices)
	for (var i = 1; i < train.trainCars(); i++) {
		renderCart(ctx, state, train, i, matrices);
	}
}

function renderHead(ctx, state, train, i, matrices){
	// WHEELS
	let radius = 2.5;

	matrices.pushPose();
	matrices.translate(0.0, 0.25, 3.5);
	ctx.drawCarModel(bogieModel["obj2"], i, matrices);
	matrices.popPose();

	matrices.pushPose();
	matrices.translate(0.0, 0.25, -4);
	ctx.drawCarModel(bogieModel["obj2"], i, matrices);
	matrices.popPose();

	matrices.pushPose();
	matrices.translate(0.0, -0.4, 4.5);
	matrices.rotateX(state.wheelAngle * radius)
	ctx.drawCarModel(bogieModel["obj1"], i, matrices);
	matrices.popPose();

	matrices.pushPose();
	matrices.translate(0.0, -0.4, 2.5);
	matrices.rotateX(state.wheelAngle * radius)
	ctx.drawCarModel(bogieModel["obj1"], i, matrices);
	matrices.popPose();

	matrices.pushPose();
	matrices.translate(0.0, -0.4, -5);
	matrices.rotateX(state.wheelAngle * radius)
	ctx.drawCarModel(bogieModel["obj1"], i, matrices);
	matrices.popPose();

	matrices.pushPose();
	matrices.translate(0.0, -0.4, -3);
	matrices.rotateX(state.wheelAngle * radius)
	ctx.drawCarModel(bogieModel["obj1"], i, matrices);
	matrices.popPose();

	// roll
	matrices.pushPose();

	let rollCoef = pseudoSin((state.rockingZCoef + i * 0.2) % 1.0);
	let speedCoef = clamp(train.speed() * 2 + 0.2, 0, 1);
	let totalCoef = rollCoef * speedCoef * 0.01 * (1 + state.curvyRailCoef * 1);
	matrices.rotateZ(totalCoef);
	// DISPLAY

	ctx.drawCarModel(state.dh.model, i, matrices);
	ctx.drawCarModel(state.dh2.model, i, matrices);

	ctx.drawCarModel(state.numModels["" + i], i, matrices);
	// NUMBER


	// PANTO

	ctx.drawCarModel(models["pantoup"], i, matrices);

	// KUZOV

	ctx.drawCarModel(models["ext"], i, matrices);
	ctx.drawCarModel(models["int"], i, matrices);
	ctx.drawCarModel(models["cabi"], i, matrices);
	ctx.drawCarModel(models["lamp"], i, matrices);

	if (shouldRenderWindows) ctx.drawCarModel(models["win"], i, matrices);

	// LIGHTS

	let shouldRenderLights = MinecraftClient.worldDayTime() % 24000 >= 11000;

	if (shouldRenderLights) {
		ctx.drawCarModel(models["fary"], i, matrices);
		ctx.drawCarModel(models["faryfr"], i, matrices);

	} else {
		ctx.drawCarModel(models["fary2"], i, matrices);
		ctx.drawCarModel(models["faryfr2"], i, matrices);
	}
	// WIPERS

	let wcoef = state.wipeCoef;

	matrices.pushPose();
	matrices.translate(0.3834, 0.9540, 7.517);
	matrices.rotate(0, 0.0628, 0.998, -0.3 + 1.1*wipFunc(wcoef));
	matrices.translate(-0.3834, -0.9540, -7.517);
	ctx.drawCarModel(models["dvor"], i, matrices);
	matrices.popPose();


	// DOORS
	let valClamped = 0.0
	if (train.doorRightOpen[i]) {
		valClamped = clamp(train.doorValue() * doorCoef, 0, 1)
	}

	let doorVal = smoothCubic(valClamped); 

	matrices.pushPose();
	matrices.translate(doorVal * (-0.11), 0.0, doorVal * -1.42);
	ctx.drawCarModel(models["door1"], i, matrices);
	ctx.drawCarModel(models["door1i"], i, matrices);

	if (shouldRenderWindows) ctx.drawCarModel(models["wdoor1"], i, matrices);

	matrices.popPose();

	matrices.pushPose();
	matrices.translate(0.0, 0.0, doorVal * -1.4);
	ctx.drawCarModel(models["door2"], i, matrices);
	ctx.drawCarModel(models["door2i"], i, matrices);

	if (shouldRenderWindows) ctx.drawCarModel(models["wdoor2"], i, matrices);

	matrices.popPose();

	matrices.pushPose();
	matrices.translate(doorVal * (-0.11), 0.0, doorVal * 1.42);
	ctx.drawCarModel(models["door3"], i, matrices);
	ctx.drawCarModel(models["door3i"], i, matrices);

	if (shouldRenderWindows) ctx.drawCarModel(models["wdoor3"], i, matrices);

	matrices.popPose();


	matrices.popPose();
}

function renderCart(ctx, state, train, i, matrices){
	// WHEELS
	let radius = 2.5;

	matrices.pushPose();
	matrices.translate(0.0, 0.25, 3.5);
	ctx.drawCarModel(bogieModel["obj2"], i, matrices);
	matrices.popPose();

	matrices.pushPose();
	matrices.translate(0.0, 0.25, -4);
	ctx.drawCarModel(bogieModel["obj2"], i, matrices);
	matrices.popPose();

	matrices.pushPose();
	matrices.translate(0.0, -0.4, 4.5);
	matrices.rotateX(state.wheelAngle * radius)
	ctx.drawCarModel(bogieModel["obj1"], i, matrices);
	matrices.popPose();

	matrices.pushPose();
	matrices.translate(0.0, -0.4, 2.5);
	matrices.rotateX(state.wheelAngle * radius)
	ctx.drawCarModel(bogieModel["obj1"], i, matrices);
	matrices.popPose();

	matrices.pushPose();
	matrices.translate(0.0, -0.4, -5);
	matrices.rotateX(state.wheelAngle * radius)
	ctx.drawCarModel(bogieModel["obj1"], i, matrices);
	matrices.popPose();

	matrices.pushPose();
	matrices.translate(0.0, -0.4, -3);
	matrices.rotateX(state.wheelAngle * radius)
	ctx.drawCarModel(bogieModel["obj1"], i, matrices);
	matrices.popPose();

	// roll
	matrices.pushPose();

	let rollCoef = pseudoSin((state.rockingZCoef + i * 0.2) % 1.0);
	let speedCoef = clamp(train.speed() * 2 + 0.2, 0, 1);
	let totalCoef = rollCoef * speedCoef * 0.01 * (1 + state.curvyRailCoef * 1);
	matrices.rotateZ(totalCoef);
	// DISPLAY

	ctx.drawCarModel(state.dh2.model, i, matrices);

	ctx.drawCarModel(state.numModels["" + i], i, matrices);
	// NUMBER


	// PANTO

	ctx.drawCarModel(models["pantodown"], i, matrices);

	// KUZOV

	ctx.drawCarModel(models["ext"], i, matrices);
	ctx.drawCarModel(models["int"], i, matrices);
	ctx.drawCarModel(models["cab"], i, matrices);
	ctx.drawCarModel(models["lamp"], i, matrices);

	if (shouldRenderWindows) ctx.drawCarModel(models["win"], i, matrices);

	// LIGHTS

	let shouldRenderLights = MinecraftClient.worldDayTime() % 24000 >= 11000;

	if (shouldRenderLights) {
		ctx.drawCarModel(models["fary"], i, matrices);
		ctx.drawCarModel(models["faryfr2"], i, matrices);

	} else {
		ctx.drawCarModel(models["fary2"], i, matrices);
		ctx.drawCarModel(models["faryfr2"], i, matrices);
	}
	// WIPERS

	let wcoef = 0.0;

	matrices.pushPose();
	matrices.translate(0.3834, 0.9540, 7.517);
	matrices.rotate(0, 0.0628, 0.998, -0.3 + 1.1*wipFunc(wcoef));
	matrices.translate(-0.3834, -0.9540, -7.517);
	ctx.drawCarModel(models["dvor"], i, matrices);
	matrices.popPose();


	// DOORS
	let valClamped = 0.0
	if (train.doorRightOpen[i]) {
		valClamped = clamp(train.doorValue() * doorCoef, 0, 1)
	}
	let doorVal = smoothCubic(valClamped); 

	matrices.pushPose();
	matrices.translate(doorVal * (-0.11), 0.0, doorVal * -1.42);
	ctx.drawCarModel(models["door1"], i, matrices);
	ctx.drawCarModel(models["door1i"], i, matrices);

	if (shouldRenderWindows) ctx.drawCarModel(models["wdoor1"], i, matrices);

	matrices.popPose();

	matrices.pushPose();
	matrices.translate(0.0, 0.0, doorVal * -1.4);
	ctx.drawCarModel(models["door2"], i, matrices);
	ctx.drawCarModel(models["door2i"], i, matrices);

	if (shouldRenderWindows) ctx.drawCarModel(models["wdoor2"], i, matrices);

	matrices.popPose();

	matrices.pushPose();
	matrices.translate(doorVal * (-0.11), 0.0, doorVal * 1.42);
	ctx.drawCarModel(models["door3"], i, matrices);
	ctx.drawCarModel(models["door3i"], i, matrices);

	if (shouldRenderWindows) ctx.drawCarModel(models["wdoor3"], i, matrices);

	matrices.popPose();


	matrices.popPose();
}

