//
//  ImprovementLayer.swift
//  SmartColony
//
//  Created by Michael Rommel on 13.04.20.
//  Copyright © 2020 Michael Rommel. All rights reserved.
//

import SpriteKit
import SmartAILibrary

class ImprovementLayer: SKNode {

    let player: AbstractPlayer?
    weak var gameModel: GameModel?
    var textureUtils: TextureUtils?

    init(player: AbstractPlayer?) {

        self.player = player

        super.init()
        self.zPosition = Globals.ZLevels.improvement
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func populate(with gameModel: GameModel?) {

        self.gameModel = gameModel

        guard let gameModel = self.gameModel else {
            fatalError("gameModel not set")
        }

        self.textureUtils = TextureUtils(with: gameModel)

        let mapSize = gameModel.mapSize()

        for x in 0..<mapSize.width() {
            for y in 0..<mapSize.height() {

                let pt = HexPoint(x: x, y: y)

                if let tile = gameModel.tile(at: pt) {

                    let screenPoint = HexPoint.toScreen(hex: pt)

                    if tile.isVisible(to: self.player) {
                        self.placeTileHex(for: tile, at: screenPoint, alpha: 1.0)
                    } else if tile.isDiscovered(by: self.player) {
                        self.placeTileHex(for: tile, at: screenPoint, alpha: 0.5)
                    }
                }
            }
        }
    }

    func placeTileHex(for tile: AbstractTile, at position: CGPoint, alpha: CGFloat) {

        let improvement = tile.improvement()

        // place farms/mines, ...
        if improvement != .none {

            let textureName = improvement.textureNamesHex().item(from: tile.point)

            let improvementSprite = SKSpriteNode(imageNamed: textureName)
            improvementSprite.position = position
            improvementSprite.zPosition = Globals.ZLevels.improvement
            improvementSprite.anchorPoint = CGPoint(x: 0, y: 0)
            improvementSprite.color = .black
            improvementSprite.colorBlendFactor = 1.0 - alpha
            self.addChild(improvementSprite)

            self.textureUtils?.set(improvementSprite: improvementSprite, at: tile.point)
        } else {
            for buildType in BuildType.allImprovements {
                if tile.buildProgress(of: buildType) > 0 {
                    print("render \(buildType) pre building animation")
                }
            }
        }

        let route = tile.route()

        if route != .none {

            if let textureName = self.textureUtils?.roadTexture(at: tile.point) {

                let routeSprite = SKSpriteNode(imageNamed: textureName)
                routeSprite.position = position
                routeSprite.zPosition = Globals.ZLevels.route
                routeSprite.anchorPoint = CGPoint(x: 0, y: 0)
                routeSprite.color = .black
                routeSprite.colorBlendFactor = 1.0 - alpha
                self.addChild(routeSprite)

                self.textureUtils?.set(routeSprite: routeSprite, at: tile.point)
            }
        }
    }

    func clear(tile: AbstractTile?) {

        guard let textureUtils = self.textureUtils else {
            fatalError("cant get textureUtils")
        }

        if let tile = tile {
            if let improvementSprite = textureUtils.improvementSprite(at: tile.point) {
                self.removeChildren(in: [improvementSprite])
            }

            if let routeSprite = textureUtils.routeSprite(at: tile.point) {
                self.removeChildren(in: [routeSprite])
            }
        }
    }

    func update(tile: AbstractTile?) {

        if let tile = tile {
            let pt = tile.point

            self.clear(tile: tile)

            let screenPoint = HexPoint.toScreen(hex: pt)

            if tile.isVisible(to: self.player) {
                self.placeTileHex(for: tile, at: screenPoint, alpha: 1.0)
            } else if tile.isDiscovered(by: self.player) {
                self.placeTileHex(for: tile, at: screenPoint, alpha: 0.5)
            }
        }
    }
}
