import Foundation
import UIKit
import Metal
import MetalKit
import SwiftSignalKit

public final class MediaEditorPreviewView: MTKView, MTKViewDelegate, RenderTarget {
    weak var renderer: MediaEditorRenderer? {
        didSet {
            if let renderer = self.renderer {
                renderer.renderTargetDidChange(self)
            }
        }
    }
    
    var drawable: MTLDrawable? {
        return self.nextDrawable
    }
    
    var nextDrawable: MTLDrawable? {
        if #available(iOS 13.0, *) {
            if let layer = self.layer as? CAMetalLayer {
                return layer.nextDrawable()
            } else {
                return self.currentDrawable
            }
        } else {
            return self.currentDrawable
        }
    }
    
    var renderPassDescriptor: MTLRenderPassDescriptor? {
        return self.currentRenderPassDescriptor
    }
    
    var mtlDevice: MTLDevice? {
        return self.device
    }
    
    public override init(frame frameRect: CGRect, device: MTLDevice?) {
        super.init(frame: frameRect, device: device)
        
        self.setup()
    }
    
    required init(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setup() {
        guard let device = MTLCreateSystemDefaultDevice() else {
            return
        }
                
        self.device = device
        self.delegate = self
        
        self.colorPixelFormat = .bgra8Unorm
        
        self.isPaused = true
        self.enableSetNeedsDisplay = true
        self.framebufferOnly = true
    }
    
    public func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
        Queue.mainQueue().justDispatch {
            self.renderer?.renderTargetDrawableSizeDidChange(size)
        }
    }
    
    public func redraw() {
        self.setNeedsDisplay()
    }
    
    public func draw(in view: MTKView) {
        guard self.frame.width > 0.0 else {
            return
        }
        self.renderer?.displayFrame()
    }
}