import Quest from "./quest";

const ORIGINAL_IMAGE_WIDTH = 651
const ORIGINAL_IMAGE_HEIGHT = 397

const DEST_IMAGE_WIDTH = 600
const DEST_IMAGE_HEIGHT = ORIGINAL_IMAGE_HEIGHT * ORIGINAL_IMAGE_WIDTH / DEST_IMAGE_WIDTH

const positions = [
	[1, 4],
	[3, 2],
	[5, 1],
	[2, 0],
]

enum STATES {
	READY,
	SCAN,
	NEXT,
	NOT_FOUND
}

export default class FindArc extends Quest {

	private step: number = 0

	private state: STATES = STATES.READY

	private img: HTMLImageElement | null = null

	private val: number = 0

	private dist: number = 0

	private selected = [0, 0]

	private timeout: number = 0

	private ready: boolean = false

	init() {
		this.img = new Image()
		this.img.src = 'img/find-arc.png'
	}

	public draw(ctx: CanvasRenderingContext2D) {
		if (!this.img) return

		ctx.drawImage(
			this.img,
			this.step * ORIGINAL_IMAGE_WIDTH, 0, ORIGINAL_IMAGE_WIDTH, ORIGINAL_IMAGE_HEIGHT,
			0, 0, DEST_IMAGE_WIDTH, DEST_IMAGE_HEIGHT
		)

		ctx.fillStyle = 'rgba(255, 255, 0, .5)'
		ctx.fillRect(this.selected[0] * 100 + 1, this.selected[1] * 85 + 1, 100, 85)

		ctx.fillStyle = '#fff'
		if (this.state === STATES.READY) {
			ctx.font = '24px sans-serif'
			ctx.textAlign = 'center'
			ctx.fillText('Выберите сектор для сканирования', 300, 500)
		}

		if (this.state === STATES.SCAN) {
			ctx.font = '16px sans-serif'
			ctx.textAlign = 'left'
			ctx.fillText('Идет поиск "Ковчега"...', 100, 490)
			this.drawBar(ctx)
		}

		if (this.state === STATES.NOT_FOUND) {
			ctx.font = '16px sans-serif'
			ctx.textAlign = 'left'
			ctx.fillText('"Ковчега" в данном секторе нет', 100, 490)
			this.drawBar(ctx)
		}

		if (this.state === STATES.NEXT) {
			ctx.font = '16px sans-serif'
			ctx.textAlign = 'left'
			ctx.fillText('"Ковчег" находится в пределах этого сектора', 100, 490)
			this.drawBar(ctx)
		}
	}

	private drawBar(ctx) {
		ctx.fillStyle = 'hsl(' + (this.val * 120) + ', 100%, 50%)'
		ctx.strokeStyle = ctx.fillStyle
		ctx.fillRect(100, 500, Math.min(this.val, 1) * 400, 30)

		ctx.beginPath()
		ctx.moveTo(100 - 1, 500 + 7)
		ctx.lineTo(100 - 1, 500 - 1)
		ctx.lineTo(100 - 1 + 7, 500 - 1)

		ctx.moveTo(100 - 1, 500 + 23)
		ctx.lineTo(100 - 1, 500 + 30 + 1)
		ctx.lineTo(100 - 1 + 7, 500 + 30 + 1)

		ctx.moveTo(100 + 1 + 400, 500 + 7)
		ctx.lineTo(100 + 1 + 400, 500 - 1)
		ctx.lineTo(100 + 1 + 400 - 7, 500 - 1)

		ctx.moveTo(100 + 1 + 400, 500 + 23)
		ctx.lineTo(100 + 1 + 400, 500 + 30 + 1)
		ctx.lineTo(100 + 1 + 400 - 7, 500 + 30 + 1)

		ctx.stroke()
	}

	public update(dt) {
		if (this.state === STATES.SCAN) {
			this.val += dt / 2000

			if (this.val >= 1) {
				this.state = STATES.NEXT
				this.timeout = 1000
			} else if (this.val >= this.dist) {
				this.state = STATES.NOT_FOUND
				this.timeout = 1000
			}
		}

		if (this.state === STATES.NOT_FOUND) {
			this.timeout -= dt
			if (this.timeout <= 0) {
				this.state = STATES.READY
			}
		}

		if (this.state === STATES.NEXT) {
			this.timeout -= dt
			if (this.timeout <= 0) {
				this.state = STATES.READY
				if (this.step === positions.length - 1) {
					this.ready = true
				} else {
					this.step++
				}
			}
		}
	}

	public click(x, y) {
		this.state = STATES.SCAN

		this.selected = [
			x / 100 | 0,
			Math.min(y / 85 | 0, 4)
		]

		const position = positions[this.step]
		this.dist = 1 - Math.hypot(this.selected[0] - position[0], this.selected[1] - position[1]) / 6
		this.val = 0
	}

	public getCursor(x, y) {
		if (this.state === STATES.READY) {
			this.selected = [
				x / 100 | 0,
				Math.min(y / 85 | 0, 4)
			]
		}

		return 'default'
	}

	public get result() {
		return this.ready
	}
}
