// http://blog.human-friendly.com/drawing-images-from-pixel-data-in-swift
// https://github.com/FlexMonkey/MetalReactionDiffusion/blob/1ea9aa4a841d20e0b247505fdf716cd5fe1a01fd/MetalReactionDiffusion/ViewController.swift

public struct PixelData {
    var a:UInt8 = 255
    var r:UInt8
    var g:UInt8
    var b:UInt8
}

private let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
private let bitmapInfo:CGBitmapInfo = CGBitmapInfo(CGImageAlphaInfo.PremultipliedFirst.toRaw())

public func imageFromARGB32Bitmap(pixels:[PixelData], width:UInt, height:UInt)->UIImage {
    let bitsPerComponent:UInt = 8
    let bitsPerPixel:UInt = 32
    
    assert(pixels.count == Int(width * height))
    
    var data = pixels // Copy to mutable []
    let providerRef = CGDataProviderCreateWithCFData(
            NSData(bytes: &data, length: data.count * sizeof(PixelData))
        )

    let cgim = CGImageCreate(
            width,
            height,
            bitsPerComponent,
            bitsPerPixel,
            width * UInt(sizeof(PixelData)),
            rgbColorSpace,
            bitmapInfo,
            providerRef,
            nil,
            true,
            kCGRenderingIntentDefault
        )
    return UIImage(CGImage: cgim)
}

extension UIImage {
  init(texture: MTLTexture) {
    let bitsPerComponent = 8
    let bitsPerPixel = 32
    let bytesPerRow: UInt = texture.width * 4
    let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
    let bitmapInfo:CGBitmapInfo = [.ByteOrder32Big, CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue)]
    
    let cgim = CGImageCreate(
            texture.width,
            texture.height,
            bitsPerComponent,
            bitsPerPixel,
            bytesPerRow,
            rgbColorSpace,
            bitmapInfo,
            dataProviderRefFrom(texture),
            nil,
            false,
            kCGRenderingIntentDefault
        )
        init(cgim)
  }
  
  func dataProviderRefFrom(texture: MTLTexture) -> CGDataProviderRef {
    let region = MTLRegionMake2D(0, 0, Int(texture.width), Int(texture.height))
    let pixelCount: Int = texture.width * texture.height
    var imageBytes = [UInt8](count: pixelCount * 4, repeatedValue: 0)
    let providerRef = CGDataProviderCreateWithCFData(NSData(bytes: &imageBytes, length: pixelCount * 4 * sizeof(UInt8)))
    return providerRef
  }
}