//
//  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 imageTexture: GLuint = 0

    var mSticker: PQEditVisionTrackMaterialsModel?
    var newImage: UIImage?
    deinit {
        BFLog(1, message: "image filter deinit 析构掉~")
        newImage = nil

        if imageTexture != 0 {
            glDeleteTextures(1, &imageTexture)
            imageTexture = 0
        }
        
    }

    init(sticker: PQEditVisionTrackMaterialsModel, isExport: Bool = true, showUISize: CGSize = .zero) {
        super.init(fragmentShader: PassthroughFragmentShader, numberOfInputs: 1)

        mSticker = sticker
        stickerInfo = sticker

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

        newImage = UIImage(contentsOfFile: documensDirectory + sticker.locationPath)
        //try find image file frome in BFFramework bundle
        if(newImage == nil){
            newImage = UIImage.moduleImage(named: sticker.locationPath, moduleName: "BFFramework",isAssets: false)
        }

        // 如果是预览时 对原图进行缩放处理
        if !isExport {
            let maxLength = max(showUISize.width, showUISize.height)
            newImage = newImage?.nx_scaleWithMaxLength(maxLength: CGFloat(maxLength * UIScreen.main.scale))

            BFLog(message: "newImage is \(newImage?.size.width ?? 0) \(newImage?.size.height ?? 0)")
 
        }

        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 { BFLog(2, message: "文件不存在") }
            }
        }

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

//            imageTexture = PQGPUImageTools.setupTexture(image: newImage!.cgImage!)

        } else { BFLog(2, message: "image filter init error image data is nil!") }
        
        
        // 保证是16的公倍数
        let aptImageSize =  NXAVUtil.aptSize(newImage!.size)
        if (!__CGSizeEqualToSize(aptImageSize, newImage!.size))
        {
            BFLog(2, message: "原图大小宽度不是16的倍数 \(newImage!.size)")
            newImage = newImage?.nx_scaleToSize(size: aptImageSize)
            BFLog(2, message: "归16后大小 \(newImage!.size)")

        }

    }

//    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!") }
    ////        }
//    }

    open override 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(Color.white)
        renderQuadWithShader(shader, uniformSettings: uniformSettings,
                             vertexBufferObject: sharedImageProcessingContext.standardImageVBO, inputTextures: [textureProperties])
        releaseIncomingFramebuffers()

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

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

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

        BFLog(2, message: "textureCoordinates is \(textureCoordinates) image size :\(newImage!.size ) cannvasSize:\(inputSize)  files path is \(mSticker?.locationPath)")

        // imageTexture 有可能被析构导致黑屏
        if imageTexture == 0 && newImage?.cgImage != nil {
            BFLog(2, message: "imageTexture is error !!!!!重新创建")
            imageTexture = PQGPUImageTools.setupTexture(image: newImage!.cgImage!)
        }

        
        //如果设置过大小位置，使用设置值，比如水印
        if(stickerInfo?.materialPosition?.width != 0){
           textureCoordinates = [
                0.0, 0.0, // 1 bottom left
                1.0, 0.0, // 2 bottom right
                0.0, 1.0, // 3 top left
                1.0, 1.0, // 4 top right
            ]
        }
        
        let texturePropertiesimagetwo = InputTextureProperties(textureCoordinates: textureCoordinates, texture: imageTexture)

        var verticesPoint: [GLfloat] = PQGPUImageTools.getVerticesPoint(sticker: mSticker!, textureSize: newImage!.size, cannvasSize: inputSize)
        
        //如果设置过大小位置，使用设置值，比如水印
        if(stickerInfo?.materialPosition?.width != 0){
            verticesPoint = PQGPUImageTools.computeVertices(viewSize: CGSize.init(width: CGFloat(inputSize.width), height: CGFloat(inputSize.height)), _bounds: CGRect.init(x: stickerInfo?.materialPosition?.x ?? 0, y:  stickerInfo?.materialPosition?.y ?? 0, width: stickerInfo?.materialPosition?.width ?? 0, height: stickerInfo?.materialPosition?.height ?? 0))
        }
        
        // 设置融合模式支持 alpha
        glEnable(GLenum(GL_DEPTH_TEST))
        glEnable(GLenum(GL_BLEND))
        glBlendFunc(GLenum(GL_SRC_ALPHA), GLenum(GL_ONE_MINUS_SRC_ALPHA))
        
        renderQuadWithShader(shader,
                             uniformSettings: uniformSettings,
                             vertexBufferObject: PQGPUImageTools.NXGenerateVBO(for: verticesPoint),
                             
                             inputTextures: [texturePropertiesimagetwo])
        releaseIncomingFramebuffers()
    }
}
