package org.jetbrains.skiko.context

import org.jetbrains.skia.impl.getPtr
import org.jetbrains.skiko.LayerDrawScope
import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.redrawer.AbstractDirectSoftwareRedrawer
import java.lang.ref.Reference

internal class DirectSoftwareContextHandler(layer: SkiaLayer) : ContextFreeContextHandler(layer) {
    private val softwareRedrawer: AbstractDirectSoftwareRedrawer
        get() = layer.redrawer!! as AbstractDirectSoftwareRedrawer

    private var currentWidth = 0
    private var currentHeight = 0
    private fun isSizeChanged(width: Int, height: Int): Boolean {
        if (width != currentWidth || height != currentHeight) {
            currentWidth = width
            currentHeight = height
            return true
        }
        return false
    }

    override fun LayerDrawScope.initCanvas() {
        val w = scaledLayerWidth
        val h = scaledLayerHeight
        if (isSizeChanged(w, h) || surface == null) {
            disposeCanvas()
            if (w > 0 && h > 0) {
                softwareRedrawer.resize(w, h)
                surface = softwareRedrawer.acquireSurface()
                canvas = surface!!.canvas
            } else {
                surface = null
                canvas = null
            }
        }
    }

    override fun flush(scope: LayerDrawScope) {
        val surface = surface
        if (surface != null) {
            try {
                softwareRedrawer.finishFrame(getPtr(surface))
            } finally {
                Reference.reachabilityFence(surface)
            }
        }
    }
}