<commit_before>package com.soywiz.korge

import com.soywiz.klogger.Logger
import com.soywiz.korag.AG
import com.soywiz.korag.AGContainer
import com.soywiz.korag.AGInput
import com.soywiz.korge.input.Input
import com.soywiz.korge.input.Keys
import com.soywiz.korge.plugin.KorgePlugins
import com.soywiz.korge.plugin.defaultKorgePlugins
import com.soywiz.korge.resources.ResourcesRoot
import com.soywiz.korge.scene.*
import com.soywiz.korge.time.seconds
import com.soywiz.korge.view.*
import com.soywiz.korim.NativeImageSpecialReader
import com.soywiz.korim.format.readBitmap
import com.soywiz.korim.vector.render
import com.soywiz.korinject.AsyncInjector
import com.soywiz.korio.async.EventLoop
import com.soywiz.korio.async.Promise
import com.soywiz.korio.async.go
import com.soywiz.korio.lang.printStackTrace
import com.soywiz.korio.time.TimeProvider
import com.soywiz.korio.vfs.ResourcesVfs
import com.soywiz.korio.vfs.register
import com.soywiz.korma.geom.Point2d
import com.soywiz.korui.CanvasApplicationEx
import com.soywiz.korui.KoruiEventLoop
import com.soywiz.korui.ui.Frame
import kotlin.math.min
import kotlin.reflect.KClass

object Korge {
	val VERSION = KORGE_VERSION

	val logger = Logger("Korge")

	suspend fun setupCanvas(config: Config): SceneContainer {
		if (config.trace) println("Korge.setupCanvas[1]")
		val injector = config.injector

		val container = config.container!!
		val agInput = container.agInput
		val ag = container.ag
		val size = config.module.size

		injector
			.mapSingleton(Views::class) { Views(get(), get(), get(), get(), get()) }
			.mapSingleton(Input::class) { Input() }
			.mapInstance(KorgePlugins::class, defaultKorgePlugins)
			.mapInstance(Config::class, config)
			.mapInstance(AGContainer::class, container)
			.mapInstance(AG::class, ag)
			.mapPrototype(EmptyScene::class) { EmptyScene() }
			.mapSingleton(ResourcesRoot::class) { ResourcesRoot() }

		if (config.frame != null) {
			injector.mapInstance(Frame::class, config.frame)
		}

		// Register module plugins
		for (plugin in config.module.plugins) {
			defaultKorgePlugins.register(plugin)
		}

		NativeImageSpecialReader.instance.register()
		injector.mapInstance(AG::class, ag)
		if (config.trace) println("Korge.setupCanvas[1b]. EventLoop: ${config.eventLoop}")
		if (config.trace) println("Korge.setupCanvas[1c]. ag: $ag")
		if (config.trace) println("Korge.setupCanvas[1d]. debug: ${config.debug}")
		if (config.trace) println("Korge.setupCanvas[1e]. args: ${config.args.toList()}")
		if (config.trace) println("Korge.setupCanvas[1f]. size: $size")
		injector.mapInstance(EventLoop::class, config.eventLoop)
		val views = injector.get(Views::class)
		views.debugViews = config.debug
		config.constructedViews(views)
		val moduleArgs = ModuleArgs(config.args)
		if (config.trace) println("Korge.setupCanvas[2]")

		views.virtualWidth = size.width
		views.virtualHeight = size.height

		// Inject all modules
		for (plugin in defaultKorgePlugins.plugins) {
			plugin.register(views)
		}

		if (config.trace) println("Korge.setupCanvas[3]")
		ag.onReady.await()

		if (config.trace) println("Korge.setupCanvas[4]")
		injector.mapInstance(ModuleArgs::class, moduleArgs)
		injector.mapInstance(TimeProvider::class, config.timeProvider)
		injector.mapInstance<Module>(Module::class, config.module)
		config.module.init(injector)

		if (config.trace) println("Korge.setupCanvas[5]")

		val downPos = Point2d()
		val upPos = Point2d()

		fun updateMousePos() {
			// Mouse is in point coordinates, convert it to pixel coordinates
			val mouseX = agInput.mouseX.toDouble() * ag.pixelDensity
			val mouseY = agInput.mouseY.toDouble() * ag.pixelDensity

			//println("updateMousePos: $mouseX, $mouseY (${ag.pixelDensity})")
			views.input.mouse.setTo(mouseX, mouseY)
			views.mouseUpdated()
		}

		fun updateTouchPos() {
			val mouseX = agInput.touchEvent.x.toDouble()
			val mouseY = agInput.touchEvent.y.toDouble()
			//println("updateMousePos: $mouseX, $mouseY")
			views.input.mouse.setTo(mouseX, mouseY)
			views.mouseUpdated()
		}

		if (config.trace) println("Korge.setupCanvas[6]")

		val mouseMovedEvent = MouseMovedEvent()
		val mouseUpEvent = MouseUpEvent()
		val mouseClickEvent = MouseClickEvent()
		val mouseDownEvent = MouseDownEvent()

		val keyDownEvent = KeyDownEvent()
		val keyUpEvent = KeyUpEvent()
		val keyTypedEvent = KeyTypedEvent()

		fun AGInput.KeyEvent.copyTo(e: KeyEvent) {
			e.keyCode = this.keyCode
		}

		// MOUSE
		agInput.onMouseDown {
			views.input.mouseButtons = 1
			updateMousePos()
			downPos.copyFrom(views.input.mouse)
			views.dispatch(mouseDownEvent)
		}
		agInput.onMouseUp {
			views.input.mouseButtons = 0
			updateMousePos()
			upPos.copyFrom(views.input.mouse)
			views.dispatch(mouseUpEvent)
		}
		agInput.onMouseOver {
			updateMousePos()
			views.dispatch(mouseMovedEvent)
		}
		agInput.onMouseClick {
			updateMousePos()
			views.dispatch(mouseClickEvent)
		}

		// TOUCH
		var moveMouseOutsideInNextFrame = false
		agInput.onTouchStart {
			views.input.mouseButtons = 1
			updateTouchPos()
			downPos.copyFrom(views.input.mouse)
			views.dispatch(mouseDownEvent)
		}
		agInput.onTouchEnd {
			views.input.mouseButtons = 0
			updateTouchPos()
			upPos.copyFrom(views.input.mouse)
			views.dispatch(mouseUpEvent)

			moveMouseOutsideInNextFrame = true
		}
		agInput.onTouchMove {
			updateTouchPos()
			views.dispatch(mouseMovedEvent)
		}

		// KEYS
		agInput.onKeyDown {
			views.input.setKey(it.keyCode, true)<commit_msg>Fixes events<commit_after>package com.soywiz.korge

import com.soywiz.klock.Klock
import com.soywiz.klogger.Logger
import com.soywiz.korag.AG
import com.soywiz.korag.AGContainer
import com.soywiz.korag.AGInput
import com.soywiz.korge.input.Input
import com.soywiz.korge.input.Keys
import com.soywiz.korge.plugin.KorgePlugins
import com.soywiz.korge.plugin.defaultKorgePlugins
import com.soywiz.korge.resources.ResourcesRoot
import com.soywiz.korge.scene.*
import com.soywiz.korge.time.seconds
import com.soywiz.korge.view.*
import com.soywiz.korim.NativeImageSpecialReader
import com.soywiz.korim.format.readBitmap
import com.soywiz.korim.vector.render
import com.soywiz.korinject.AsyncInjector
import com.soywiz.korio.async.EventLoop
import com.soywiz.korio.async.Promise
import com.soywiz.korio.async.go
import com.soywiz.korio.lang.Console
import com.soywiz.korio.lang.printStackTrace
import com.soywiz.korio.time.TimeProvider
import com.soywiz.korio.vfs.ResourcesVfs
import com.soywiz.korio.vfs.register
import com.soywiz.korma.geom.Point2d
import com.soywiz.korui.CanvasApplicationEx
import com.soywiz.korui.KoruiEventLoop
import com.soywiz.korui.ui.Frame
import kotlin.math.min
import kotlin.reflect.KClass

object Korge {
	val VERSION = KORGE_VERSION

	val logger = Logger("Korge")

	suspend fun setupCanvas(config: Config): SceneContainer {
		if (config.trace) println("Korge.setupCanvas[1]")
		val injector = config.injector

		val container = config.container!!
		val agInput = container.agInput
		val ag = container.ag
		val size = config.module.size

		injector
			.mapSingleton(Views::class) { Views(get(), get(), get(), get(), get()) }
			.mapSingleton(Input::class) { Input() }
			.mapInstance(KorgePlugins::class, defaultKorgePlugins)
			.mapInstance(Config::class, config)
			.mapInstance(AGContainer::class, container)
			.mapInstance(AG::class, ag)
			.mapPrototype(EmptyScene::class) { EmptyScene() }
			.mapSingleton(ResourcesRoot::class) { ResourcesRoot() }

		if (config.frame != null) {
			injector.mapInstance(Frame::class, config.frame)
		}

		// Register module plugins
		for (plugin in config.module.plugins) {
			defaultKorgePlugins.register(plugin)
		}

		NativeImageSpecialReader.instance.register()
		injector.mapInstance(AG::class, ag)
		if (config.trace) println("Korge.setupCanvas[1b]. EventLoop: ${config.eventLoop}")
		if (config.trace) println("Korge.setupCanvas[1c]. ag: $ag")
		if (config.trace) println("Korge.setupCanvas[1d]. debug: ${config.debug}")
		if (config.trace) println("Korge.setupCanvas[1e]. args: ${config.args.toList()}")
		if (config.trace) println("Korge.setupCanvas[1f]. size: $size")
		injector.mapInstance(EventLoop::class, config.eventLoop)
		val views = injector.get(Views::class)
		views.debugViews = config.debug
		config.constructedViews(views)
		val moduleArgs = ModuleArgs(config.args)
		if (config.trace) println("Korge.setupCanvas[2]")

		views.virtualWidth = size.width
		views.virtualHeight = size.height

		// Inject all modules
		for (plugin in defaultKorgePlugins.plugins) {
			plugin.register(views)
		}

		if (config.trace) println("Korge.setupCanvas[3]")
		ag.onReady.await()

		if (config.trace) println("Korge.setupCanvas[4]")
		injector.mapInstance(ModuleArgs::class, moduleArgs)
		injector.mapInstance(TimeProvider::class, config.timeProvider)
		injector.mapInstance<Module>(Module::class, config.module)
		config.module.init(injector)

		if (config.trace) println("Korge.setupCanvas[5]")

		val downPos = Point2d()
		val upPos = Point2d()
		val mouseMovedEvent = MouseMovedEvent()
		val mouseUpEvent = MouseUpEvent()
		val mouseClickEvent = MouseClickEvent()
		val mouseDownEvent = MouseDownEvent()

		val keyDownEvent = KeyDownEvent()
		val keyUpEvent = KeyUpEvent()
		val keyTypedEvent = KeyTypedEvent()
		var downTime = 0.0
		var moveTime = 0.0
		var upTime = 0.0

		fun mouseDown(name: String, x: Int, y: Int) {
			//Console.log("mouseDown: $name")
			views.input.mouseButtons = 1
			views.input.mouse.setTo(x * ag.pixelDensity, y * ag.pixelDensity)
			views.mouseUpdated()
			downPos.copyFrom(views.input.mouse)
			views.dispatch(mouseDownEvent)
			downTime = Klock.currentTimeMillisDouble()
		}

		fun mouseMove(name: String, x: Int, y: Int) {
			//Console.log("mouseMove: $name")
			views.input.mouse.setTo(x * ag.pixelDensity, y * ag.pixelDensity)
			views.mouseUpdated()
			views.dispatch(mouseMovedEvent)
			moveTime = Klock.currentTimeMillisDouble()
		}

		fun mouseUp(name: String, x: Int, y: Int) {
			//Console.log("mouseUp: $name")
			views.input.mouseButtons = 0
			views.input.mouse.setTo(x * ag.pixelDensity, y * ag.pixelDensity)
			views.mouseUpdated()
			upPos.copyFrom(views.input.mouse)
			views.dispatch(mouseUpEvent)
			upTime = Klock.currentTimeMillisDouble()
			if ((downTime - upTime) <= 40.0) {
				//Console.log("mouseClick: $name")
				views.dispatch(mouseClickEvent)
			}
		}

		fun AGInput.KeyEvent.copyTo(e: KeyEvent) {
			e.keyCode = this.keyCode
		}

		// MOUSE
		agInput.onMouseDown { e -> mouseDown("onMouseDown", e.x, e.y) }
		agInput.onMouseUp { e -> mouseUp("onMouseUp", e.x, e.y) }
		agInput.onMouseOver { e -> mouseMove("onMouseOver", e.x, e.y) }
		//agInput.onMouseClick { e -> } // Triggered by mouseUp

		// TOUCH
		var moveMouseOutsideInNextFrame = false
		agInput.onTouchStart { e -> mouseDown("onTouchStart", e.x, e.y) }
		agInput.onTouchEnd { e -> mouseUp("onTouchEnd", e.x, e.y); moveMouseOutsideInNextFrame = true }
		agInput.onTouchMove { e -> mouseMove("onTouchMove", e.x, e.y) }

		// KEYS
		agInput.onKeyDown {
			views.input.setKey(it.keyCode, true)
{'fraction_non_alphanumeric': 0.12828620471587315, 'fraction_numerical': 0.003794380702863854, 'mean_word_length': 4.590909090909091, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5624616', 'n_tokens_mistral': 4273, 'n_tokens_neox': 3945, 'n_words': 667}