//
//  PQImageFilter.swift
//  GPUImage_macOS
//
//  Created by ak on 2020/8/13.
//  Copyright © 2020 Sunset Lake Software LLC. All rights reserved.
//

import Foundation
import Kingfisher
import KingfisherWebP
import UIKit

open class PQImageFilter: PQBaseFilter {
    var widthOfImage: Int32!
    var heightOfImage: Int32!

    // 图片纹理
    var imageTexture: GLuint = 0

    var mSticker: PQEditVisionTrackMaterialsModel?

    var newImage: UIImage?

    deinit {
        BFLog(message: "image filter deinit 析构掉~")
        newImage = nil
        
        if(imageTexture != 0){
            glDeleteTextures(1,&imageTexture)
            imageTexture = 0
        }
    }

    init(sticker: PQEditVisionTrackMaterialsModel) {
        super.init(fragmentShader: PassthroughFragmentShader, numberOfInputs: 1)

        mSticker = sticker
        stickerInfo = sticker

        if mSticker!.locationPath.count == 0 {
            FilterLog(message: "图片数据为空，创建失败")
            return
        }
        print("mSticker path : \(String(describing: mSticker!.locationPath))")

        newImage = UIImage(contentsOfFile: documensDirectory + sticker.locationPath)

        // 保证是16的公倍数
        //        let aptImageSize =  NXAVUtil.aptSize(newImage!.size)
        //        if (!__CGSizeEqualToSize(aptImageSize, newImage!.size))
        //        {
        //
        //            FilterLog(message: "原图大小宽度不是16的倍数 \(newImage!.size)")
        //
        //            newImage = newImage?.nx_scaleToSize(size: aptImageSize)
        //
        //            FilterLog(message: "归16后大小 \(newImage!.size)")
        //
        //        }
        autoreleasepool {
            if newImage == nil {
                let filePath = documensDirectory + (mSticker?.locationPath ?? "")
                if FileManager.default.fileExists(atPath: filePath) {
                    // 有可能是 WEBP
                    let fileData: Data = try! Data(contentsOf: URL(fileURLWithPath: filePath))
                    if fileData.count != 0, fileData.isWebPFormat {
                        newImage = WebPProcessor.default.process(item: ImageProcessItem.data(fileData), options: KingfisherParsedOptionsInfo([.onlyLoadFirstFrame, .scaleFactor(1)]))
                    }
                } else { FilterLog(message: "文件不存在") }
            }
        }

        if newImage != nil {
            BFLog(message: "提前加载图片。。。。timelineIn : \(String(describing: mSticker?.timelineIn)) timelineOut :\(String(describing: mSticker?.timelineOut)) \(String(describing: mSticker?.locationPath))")
            
            imageTexture = PQGPUImageTools.setupTexture(image: newImage!.cgImage!)

        } else { FilterLog(message: "image filter init error image data is nil!") }
    }

    override public func newFramebufferAvailable(_ framebuffer: Framebuffer, fromSourceIndex: UInt) {
        super.newFramebufferAvailable(framebuffer, fromSourceIndex: fromSourceIndex)

        let currTime = CMTimeGetSeconds(CMTime(value: framebuffer.timingStyle.timestamp!.value, timescale: framebuffer.timingStyle.timestamp!.timescale))
        if mSticker!.timelineIn != 0, currTime >= mSticker!.timelineIn, currTime <= mSticker!.timelineOut, imageTexture == 0 {
            if newImage != nil {
//                imageTexture = PQGPUImageTools.setupTexture(image: newImage!.cgImage!)
            } else { BFLog(message: "image filter init error image data is nil!") }
        }
    }

    override open func renderFrame() {
        let inputFramebuffer: Framebuffer = inputFramebuffers[0]!
        let inputSize = inputFramebuffer.sizeForTargetOrientation(.portrait)

        print("renderFrame timestamp is \(inputFramebuffer.timingStyle)")

        let currTime = CMTimeGetSeconds(CMTime(value: inputFramebuffer.timingStyle.timestamp!.value, timescale: inputFramebuffer.timingStyle.timestamp!.timescale))

        renderFramebuffer = sharedImageProcessingContext.framebufferCache.requestFramebufferWithProperties(orientation: .portrait, size: inputSize, stencil: false)

        // 画布
        let textureProperties = InputTextureProperties(textureCoordinates: inputFramebuffer.orientation.rotationNeededForOrientation(.portrait).textureCoordinates(), texture: inputFramebuffer.texture)

        renderFramebuffer.activateFramebufferForRendering()
        clearFramebufferWithColor(backgroundColor)
        renderQuadWithShader(shader, uniformSettings: uniformSettings,
                             vertexBufferObject: sharedImageProcessingContext.standardImageVBO, inputTextures: [textureProperties])
        releaseIncomingFramebuffers()

        if newImage == nil {
            FilterLog(message: "图片数据有错误！！！！ 检查数据\(mSticker!.locationPath)")
            return
        }

        FilterLog(message: " image filter 当前时间: \(currTime) \(newImage!.size)")

//        if currTime >= mSticker!.timelineIn && currTime <= mSticker!.timelineOut {
            FilterLog(message: " 显示图片当前时间: \(currTime) 开始时间：\(mSticker!.timelineIn) 结束时间：\(mSticker!.timelineOut)  \(String(describing: newImage?.size))")
            // 取纹理坐标
            let textureCoordinates = PQGPUImageTools.getTextureCoordinates(sticker: mSticker!, textureSize: newImage!.size, cannvasSize: inputSize)

            FilterLog(message: "textureCoordinates is \(textureCoordinates)")
            
            //imageTexture 有可能被析构导致黑屏
            if(imageTexture == 0){
                FilterLog(message: "imageTexture is error !!!!!")
                imageTexture = PQGPUImageTools.setupTexture(image: newImage!.cgImage!)
            }
        
            let texturePropertiesimagetwo = InputTextureProperties(textureCoordinates: textureCoordinates, texture: imageTexture)

            let verticesPoint: [GLfloat] = PQGPUImageTools.getVerticesPoint(sticker: mSticker!, textureSize: newImage!.size, cannvasSize: inputSize)
            renderQuadWithShader(shader,
                                 uniformSettings: uniformSettings,
                                 vertexBufferObject: PQGPUImageTools.NXGenerateVBO(for: verticesPoint),

                                 inputTextures: [texturePropertiesimagetwo])
            releaseIncomingFramebuffers()
 
    }
}
