//
//  Cave.swift
//
//  Copyright © 2020 Apple Inc. All rights reserved.
//


import SpriteKit
import UIKit
import SPCScene
import Canvas
import SwansQuest
import PlaygroundSupport

public class Cave : Scene, SceneAnimating {
    static let brick = #imageLiteral(resourceName: "CaveBackground-Floor-64.png")
    static let background = #imageLiteral(resourceName: "Background-Brick-64.png")
    static let stairsFull = #imageLiteral(resourceName: "CaveStairs_64-full.png")
    static let stairsHalf = #imageLiteral(resourceName: "CaveStairs_64-half.png")
    
    public var torch1 = Torch(name: "torch1")
    public var torch2 = Torch(name: "torch2")
    public var torch3 = Torch(name: "torch3")
    public var torch4 = Torch(name: "torch4")
    public var torch5 = Torch(name: "torch5")
    public var torch6 = Torch(name: "torch6")
    
    var hero: Hero
    var torchOrder: [Torch]
    var waypoints: [Point]
    var torchpoints: [Point]
    var lightNode: SKLightNode
    
    public override init() {
        hero = Hero()
        hero.lightingBitMask = 0b0001
        
        torchOrder = [torch3, torch2, torch6, torch1, torch5, torch4]
        
        waypoints = [
            Point(x: -308, y: 448),
            Point(x: 352, y: 256),
            Point(x: -256, y: 192),
            Point(x: 96, y: 0),
            Point(x: -224, y: -256),
            Point(x: 296, y: -384)
        ]
        
        torchpoints = [
            Point(x: -308, y: 637),
            Point(x: 352, y: 637),
            Point(x: -637, y: 192),
            Point(x: 637, y: 128),
            Point(x: -637, y: -256),
            Point(x: 637, y: -637)
        ]
        
        lightNode = SKLightNode.torch(at: Point(x: -308, y: 637))
        lightNode.lightColor = .black
        
        super.init(size: Scene.sceneSize)
        clearLights()
        prepareLayout()
        
        addChild(lightNode)
        torchOrder.forEach { $0.lightingBitMask = 0b0001 }
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    // MARK: - SceneAnimating
    
    public var sceneTransition: SKTransition?
    public var animationDelegate: SceneAnimatingDelegate?
    public var loadingDescription: String? {
        didSet {
            enableAccessibility(label: loadingDescription!)
        }
    }
    
    public func sceneIsPresented() {
        if let desc = loadingDescription {
            UIAccessibility.post(notification: .announcement, argument: desc)
        }

        animationDelegate?.sceneDidLoad(self)
        
        let shouldPass = torchOrder.map { $0.shouldActivate }
        
        for (i, pass) in shouldPass.enumerated() {
            guard pass else {
                PlaygroundPage.current.assessmentStatus = .fail(hints: ["The darkness confounds!! You must set the accessibility label for each of the torches, or be forever lost in this cave. I see `\(torchOrder[i].name!)` is not lit"], solution: nil)
                return
            }
            if lightNode.parent != nil {
                lightNode.removeFromParent()
            }
            
            torchOrder[i].activate()
            addChild(SKLightNode.torch(at: torchpoints[i]))
            
            self.place(hero, at: waypoints[i])
        }
        
        PlaygroundPage.current.assessmentStatus = .pass(message: nil)
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            let message = "Congratulations, you've lit every torch and our Hero has made it to the other side of the Cave."
            UIAccessibility.post(notification: .announcement, argument: message)
        }
        hero.run(SKAction.wait(forDuration: 4.0)) {
            self.animationDelegate?.sceneDidFinishAnimations(self)
        }
        
    }
    
    public func sceneWillDismiss() {
        
    }
    
    // MARK: - Cave Layout
    
    public func prepareLayout() {
        let bg = Sprite(image: Image(with: Cave.background), columns: 16, rows: 16, name: "Cave Background")
        bg.lightingBitMask = 0b0001
        self.place(bg, at: Point.center)
        
        // TODO: Place Torches
        self.place(torch3, at: Point(x: -224, y: 448))
        self.place(torch2, at: Point(x: 352, y: 448))
        self.place(torch6, at: Point(x: -352, y: 192))
        self.place(torch1, at: Point(x: 192, y: 0))
        self.place(torch5, at: Point(x: -320, y: -256))
        self.place(torch4, at: Point(x: 388, y: -384))
        
        // Perimeter
        let left = Sprite(image: Image(with: Cave.brick), columns: 1, rows: 16)
        left.lightingBitMask = 0b0001
        self.place(left, at: Point(x: -480.0, y: 0.0))
        let right = Sprite(image: Image(with: Cave.brick), columns: 1, rows: 13)
        right.lightingBitMask = 0b0001
        self.place(right, at: Point(x: 480.0, y: 96.0))
        
        // Level 1
        let level1 = Sprite(image: Image(with: Cave.brick), columns: 10, rows: 1)
        level1.lightingBitMask = 0b0001
        self.place(level1, at: Point(x: -128.0, y: 352.0))
        let level1B = Sprite(image: Image(with: Cave.brick), columns: 6, rows: 1)
        level1B.lightingBitMask = 0b0001
        self.place(level1B, at: Point(x: -320.0, y: 288.0))
        
        // Level 2
        let level2 = Sprite(image: Image(with: Cave.brick), columns: 5, rows: 1)
        level2.lightingBitMask = 0b0001
        self.place(level2, at: Point(x: 288.0, y: 160.0))
        let level2B = Sprite(image: Image(with: Cave.brick), columns: 12, rows: 1)
        level2B.lightingBitMask = 0b0001
        self.place(level2B, at: Point(x: 64.0, y: 96.0))
        
        let stair2 = Graphic(image: Image(with: Cave.stairsFull))
        stair2.lightingBitMask = 0b0001
        self.place(stair2, at: Point(x: 96.0, y: 160.0))
        let stair2b = Graphic(image: Image(with: Cave.stairsHalf))
        stair2b.lightingBitMask = 0b0001
        self.place(stair2b, at: Point(x: 32.0, y: 160.0))
        
        // Level 3
        let level3 = Sprite(image: Image(with: Cave.brick), columns: 5, rows: 1)
        level3.lightingBitMask = 0b0001
        self.place(level3, at: Point(x: -288.0, y: -96.0))
        let level3B = Sprite(image: Image(with: Cave.brick), columns: 5, rows: 1)
        level3B.lightingBitMask = 0b0001
        self.place(level3B, at: Point(x: 160.0, y: -96.0))
        
        // Level 4
        let level4 = Sprite(image: Image(with: Cave.brick), columns: 5, rows: 1)
        level4.lightingBitMask = 0b0001
        self.place(level4, at: Point(x: 288.0, y: -288.0))
        
        // Base
        let base = Sprite(image: Image(with: Cave.brick), columns: 16, rows: 1)
        base.lightingBitMask = 0b0001
        self.place(base, at: Point(x: 0, y: -480))
        let baseA = Sprite(image: Image(with: Cave.brick), columns: 7, rows: 1)
        baseA.lightingBitMask = 0b0001
        self.place(baseA, at: Point(x:-224.0 , y: -416))
        let baseB = Sprite(image: Image(with: Cave.brick), columns: 5, rows: 1)
        baseB.lightingBitMask = 0b0001
        self.place(baseB, at: Point(x:-288.0 , y: -352))
        
        let stairB = Graphic(image: Image(with: Cave.stairsFull))
        stairB.lightingBitMask = 0b0001
        self.place(stairB, at: Point(x: -96, y: -352))
        let stairB1 = Graphic(image: Image(with: Cave.stairsHalf))
        stairB1.lightingBitMask = 0b0001
        self.place(stairB1, at: Point(x: -32, y: -352))
        
        let stairB2 = Graphic(image: Image(with: Cave.stairsFull))
        stairB2.lightingBitMask = 0b0001
        self.place(stairB2, at: Point(x: 32, y: -416))
        let stairB3 = Graphic(image: Image(with: Cave.stairsHalf))
        stairB3.lightingBitMask = 0b0001
        self.place(stairB3, at: Point(x: 96, y: -416))
        
    }
}


public class CaveEntrance : Scene, SceneAnimating {
    static let background = #imageLiteral(resourceName: "WalkToCave_1024.png")
    static let ground = -290.0
    
    var hero : Hero
    var bg: Graphic
    
    public init(with: Hut.HeroContents = .nothing) {
        hero = Hero()
        bg = Graphic(image: Image(with: CaveEntrance.background), name: "Entrance to Cave")
        bg.enableAccessibility(label: "An audio description")
        
        super.init(size: Scene.sceneSize)
        
        hero.holding = with.loadout
        
        self.place(bg, at: Point.center)
        self.place(hero, at: Point(x: -40, y: CaveEntrance.ground))
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - SceneAnimating
    
    public var sceneTransition: SKTransition?
    public var animationDelegate: SceneAnimatingDelegate?
    public var loadingDescription: String? {
        didSet {
            enableAccessibility(label: loadingDescription!)
        }
    }
    
    public func sceneIsPresented() {
        animationDelegate?.sceneDidLoad(self)
        
        hero.walk(distance: 340.0, completion: {})
        hero.run(SKAction.wait(forDuration: 4.0)) {
            self.animationDelegate?.sceneDidFinishAnimations(self)
        }
    }
    
    public func sceneWillDismiss() {
        
    }
}
