//
//  DropScene.swift
//  BookCore
//
//  Created by 日々野清高 on 2021/03/26.
//

import Foundation
import SpriteKit
import AVFoundation

class DropScene: SKScene, SKPhysicsContactDelegate {
    var jewel:SKSpriteNode!
    var backgroundImage:SKSpriteNode!
    var floorImage:SKSpriteNode!
    var backgroundMusic:SKAudioNode!
    var cSound:SKAudioNode!
    var cSound2:SKAudioNode!
    var dropWait:Bool = false
    let Box: UInt32 = 1 << 1
    public override func didMove(to view: SKView) {
        //サウンドの準備
        prepareAudioNodes()
       // let cs = SKAudioNode(fileNamed: "sound03.mp3")
       // let cs2 = SKAudioNode(fileNamed: "sound02.mp3")
       // cSound = cs
       // cSound2 = cs2
       // cSound.autoplayLooped = false
       // cSound2.autoplayLooped = false
       // self.addChild(cSound)
       // self.addChild(cSound2)
        //オーディオノードを作成し追加する。
       // let bgm = SKAudioNode(fileNamed: "example.mp3")
       // backgroundMusic = bgm
       // backgroundMusic.run(SKAction.stop())
       // addChild(backgroundMusic)
        //let csnd = SKAudioNode(fileNamed: "sound01.mp3")
        //cSound = csnd
        //cSound.autoplayLooped = false
        //cSound.run(SKAction.stop())
        //addChild(cSound)

        //衝突デレゲートを自分に
        physicsWorld.contactDelegate = self

        // フレームサイズを、ビューの境界と同じにします。
        self.size = view.bounds.size

        // 重力の向きと強さを設定。
        self.physicsWorld.gravity = CGVector(dx: 0.0, dy: -2.4)
        // エッジを作ってノードが画面からはみ出さないようにします。
        self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
        self.physicsBody?.restitution = 0.0 //弾性係数
        self.name = "scene"
        //シーンの背景色
        self.backgroundColor = SKColor.gray
        
        let bg = SKSpriteNode(imageNamed: "background.png")
        backgroundImage = bg
        backgroundImage.size = CGSize(width: 200, height: 200)
        backgroundImage.position = CGPoint(x: size.width/2, y: size.height/2 + 3)
        addChild(backgroundImage)
        //床
        let floor = SKSpriteNode(imageNamed: "floor.png")
        floorImage = floor
        floorImage.size = CGSize(width: 200, height: 8)
        floorImage.position = CGPoint(x: size.width/2, y: 2)
        // 物理的な性質をもたせる。（これで重力に従う。）
        floorImage.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width:200 ,height:5))
        floorImage.physicsBody?.restitution = 0.0 //弾性係数0.0〜1.0
        floorImage.physicsBody?.allowsRotation = false //回転許可
        floorImage.physicsBody?.friction = 0.0 //摩擦0.0〜1.0
        floorImage.physicsBody?.mass = 100.0 //重さ
        floorImage.physicsBody?.categoryBitMask = 0xFFFFFFFF //衝突カテゴリビットマスク
        floorImage.physicsBody?.contactTestBitMask = 0xFFFFFFFF //衝突検出ビットマスク
        //floorImage.physicsBody?.isDynamic = true
        addChild(floorImage)
    }
    
    private func prepareAudioNodes() {
        DispatchQueue.global().async {
            let cs = SKAudioNode(fileNamed: "sound03.mp3")
            let cs2 = SKAudioNode(fileNamed: "sound02.mp3")
            DispatchQueue.main.async {
                self.cSound = cs
                self.cSound2 = cs2
                self.cSound.autoplayLooped = false
                self.cSound2.autoplayLooped = false
                self.addChild(self.cSound)
                self.addChild(self.cSound2)
            }
        }
    }
    
    override var isUserInteractionEnabled: Bool {
        get {
            return true
        }
        set {
            // ignore
        }
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch: AnyObject in touches {
            let location = touch.location(in: self)
            let jewel = SKSpriteNode(imageNamed: "jewel01.png")
            jewel.size = CGSize(width: 20, height: 20)
            if(!dropWait) {
                dropFrame(Int(location.x / 20) + 1)
                dropWait = true
                let seconds = 0.16
                DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
                    // Put your code which should be executed with a delay here
                    self.dropWait = false
                }
                return
            }
        }
    }

    public override func update(_ currentTime: CFTimeInterval) {}
    
    public func dropZero(_ x: Int) {
        let jewel = SKSpriteNode(imageNamed: "jewel00.png")
        jewel.name = "jewel"
        jewel.size = CGSize(width: 20, height: 20)
        jewel.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width:10 ,height:20.3))
        jewel.physicsBody?.restitution = 0.0 //弾性係数0.0〜1.0
        jewel.physicsBody?.allowsRotation = false //回転許可
        jewel.physicsBody?.friction = 0.0 //摩擦0.0〜1.0
        jewel.physicsBody?.mass = 0.0 //重さ
        jewel.physicsBody?.categoryBitMask = 0xFFFFFFFF //衝突カテゴリビットマスク
        jewel.physicsBody?.contactTestBitMask = 0xFFFFFFFF
        jewel.position = CGPoint(x: CGFloat(x*20)-10, y:200.0)
        //jewel.addGlow()
        self.addChild(jewel)
    }
    
    public func dropRed(_ x: Int) {
        let jewel = SKSpriteNode(imageNamed: "jewel01.png")
        jewel.addGlow()
        jewel.name = "jewel"
        jewel.size = CGSize(width: 20, height: 20)
        jewel.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width:10 ,height:20.3))
        jewel.physicsBody?.restitution = 0.0 //弾性係数0.0〜1.0
        jewel.physicsBody?.allowsRotation = false //回転許可
        jewel.physicsBody?.friction = 0.0 //摩擦0.0〜1.0
        jewel.physicsBody?.mass = 0.0 //重さ
        jewel.physicsBody?.categoryBitMask = 0xFFFFFFFF //衝突カテゴリビットマスク
        jewel.physicsBody?.contactTestBitMask = 0xFFFFFFFF
        jewel.position = CGPoint(x: CGFloat(x*20)-10, y:200.0)

        self.addChild(jewel)



        
        // シェーダーのソースコードを文字列として指定
       /* let shaderSource = """
        void main() {
            vec2 uv = v_tex_coord;
            
            // 光の位置を計算（右上から左下に移動するように調整）
            float lightPosX = mod(-u_time * 5.0, 10.0); // スピードを速くするために係数を大きくする（1.0）
            float lightPosY = mod(-u_time * 5.0, 10.0); // スピードを速くするために係数を大きくする（1.0）

            // 光の位置を斜めに動かす
            vec2 lightPos = vec2(lightPosY, lightPosX);

            // 光の位置と現在のピクセルの距離を計算（x と y の座標を交換）
            //float distance = abs((uv.y - lightPos.y) + (uv.x - lightPos.x));
            float distance = abs((uv.y - lightPos.y) + (uv.x - lightPos.x));
            // 光の広がりを調整
            float glare = smoothstep(2.0, 0.02, distance); // 2.0 は光の幅、0.02 はスムージングの範囲

            // 元のテクスチャカラーを取得
            vec4 color = texture2D(u_texture, uv);

            // 光のエフェクトを適用するかどうかをアルファ値で制御
            if (color.a > 0.01) {
                // アルファ値が閾値以上の場合、光の反射を適用
                color.rgb += glare * vec3(1.0, 1.0, 1.0) * 0.5; // 光の強さを調整
            }

            gl_FragColor = color;
        }

        """
        
        // シェーダーを作成し、ノードに設定
        let shader = SKShader(source: shaderSource)
        jewel.shader = shader
        */

    }

    public func dropGreen(_ x: Int) {
        let jewel = SKSpriteNode(imageNamed: "jewel02.png")
        jewel.addGlow()
        jewel.name = "jewel"
        jewel.size = CGSize(width: 20, height: 20)
        jewel.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width:10 ,height:20.3))
        jewel.physicsBody?.restitution = 0.0 //弾性係数0.0〜1.0
        jewel.physicsBody?.allowsRotation = false //回転許可
        jewel.physicsBody?.friction = 0.0 //摩擦0.0〜1.0
        jewel.physicsBody?.mass = 0.0 //重さ
        jewel.physicsBody?.categoryBitMask = 0xFFFFFFFF //衝突カテゴリビットマスク
        jewel.physicsBody?.contactTestBitMask = 0xFFFFFFFF
        jewel.position = CGPoint(x: CGFloat(x*20)-10, y:200.0)

        self.addChild(jewel)
    }

    public func dropBlue(_ x: Int) {
        let jewel = SKSpriteNode(imageNamed: "jewel03.png")
        jewel.addGlow()
        jewel.name = "jewel"
        jewel.size = CGSize(width: 20, height: 20)
        jewel.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width:10 ,height:20.3))
        jewel.physicsBody?.restitution = 0.0 //弾性係数0.0〜1.0
        jewel.physicsBody?.allowsRotation = false //回転許可
        jewel.physicsBody?.friction = 0.0 //摩擦0.0〜1.0
        jewel.physicsBody?.mass = 0.0 //重さ
        jewel.physicsBody?.categoryBitMask = 0xFFFFFFFF //衝突カテゴリビットマスク
        jewel.physicsBody?.contactTestBitMask = 0xFFFFFFFF
        jewel.position = CGPoint(x: CGFloat(x*20)-10, y:200.0)
        self.addChild(jewel)
    }
    
    public func dropFrame(_ x: Int) {
        let jewel = SKSpriteNode(imageNamed: "jewel11.png")
        jewel.addGlow()
        jewel.name = "jewel"
        jewel.size = CGSize(width: 20, height: 20)
        jewel.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width:10 ,height:20.3))
        jewel.physicsBody?.restitution = 0.0 //弾性係数0.0〜1.0
        jewel.physicsBody?.allowsRotation = false //回転許可
        jewel.physicsBody?.friction = 1.0 //摩擦0.0〜1.0
        jewel.physicsBody?.mass = 0.0 //重さ
        jewel.physicsBody?.categoryBitMask = 0xFFFFFFFF //衝突カテゴリビットマスク
        jewel.physicsBody?.contactTestBitMask = 0xFFFFFFFF
        jewel.position = CGPoint(x: CGFloat(x*20)-10, y:200.0)
        self.addChild(jewel)
    }
    
    //衝突検出
    func didBegin(_ contact: SKPhysicsContact) {
        //AudioServicesPlaySystemSound(soundIdRing)
        if contact.bodyA.node?.name == "scene" || contact.bodyB.node?.name == "scene" {
            return
        }
        if (contact.bodyA.node?.name == "jewel" && contact.bodyB.node?.name == "jewel") {
            cSound.run(SKAction.stop())
            cSound.run(SKAction.play())
        } else {
            cSound2.run(SKAction.stop())
            cSound2.run(SKAction.play())
        }
    }

    //ノードを消去する処理
    public func clear() {
        //全消し
        removeAllChildren()
        addChild(backgroundImage)
        addChild(floorImage)
        addChild(cSound)
        addChild(cSound2)
    }
}

extension SKNode
{
    func addGlow(radius:CGFloat=10)
    {
        let view = SKView()
        let effectNode = SKEffectNode()
        let texture = view.texture(from: self, crop:CGRect(x: 0, y: 0, width: 20, height: 20))
        effectNode.shouldRasterize = true
        effectNode.filter = CIFilter(name: "CIGaussianBlur",parameters: ["inputRadius":radius])
        addChild(effectNode)
        effectNode.alpha = 0.4
        /*effectNode.run(.sequence([
            .wait(forDuration: 0.5),
            .repeatForever(.sequence([
                .scale(to: 1.0, duration: 0.05),
                .scale(to: 0.5, duration: 0.05),
                .wait(forDuration: 2)
            ]))
        ]))*/
        effectNode.addChild(SKSpriteNode(texture: texture))
    }
}
