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

import UIKit
import SpriteKit
import SPCScene
import SPCAudio

public struct Canvas {
    fileprivate static var scene = Scene(size: Scene.sceneSize)
    fileprivate static var view = UIView(frame: .zero)
    fileprivate static var container = UIView(frame: .zero)
    
    /// Toybox API
    
    public static func setBackground(_ image: Image) {
        parentSceneIfNotVisible()
        scene.backgroundImage = image
    }
    
    public static func add(_ graphic: BaseGraphic, at point: Point = Point.center) {
        parentSceneIfNotVisible()
        scene.place(graphic, at: point)
    }
    
    public static func present(scene newScene: Scene, transition: SKTransition?) {
        parentSceneIfNotVisible()
        guard let trans = transition else {
            scene.skView.presentScene(newScene)
            return
        }
        scene.skView.presentScene(newScene, transition: trans)
    }
    
    /// UIKit API
    
    public static func add(view other: UIView, width: CGFloat = -1.0, height: CGFloat = -1.0) {
        parentViewIfNotVisible()
        
        let parent = view
        
        parent.addSubview(other)
        other.translatesAutoresizingMaskIntoConstraints = false
        
        let w = width < 0.0 ? other.widthAnchor.constraint(equalTo: parent.widthAnchor) : other.widthAnchor.constraint(equalToConstant: width)
        let h = height < 0.0 ? other.heightAnchor.constraint(equalTo: parent.heightAnchor) : other.heightAnchor.constraint(equalToConstant: height)
        NSLayoutConstraint.activate([
            other.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            other.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            w, h
        ])
    }
    
    static func parentViewIfNotVisible() {
        guard view.superview == nil else { return }
        container.addSubview(view)
        
        view.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            view.centerXAnchor.constraint(equalTo: container.centerXAnchor),
            view.centerYAnchor.constraint(equalTo: container.centerYAnchor),
            view.widthAnchor.constraint(equalTo: container.widthAnchor),
            view.heightAnchor.constraint(equalTo: container.heightAnchor)
        ])
    }
    
    static func parentSceneIfNotVisible() {
        guard scene.skView.superview == nil else { return }
        container.addSubview(scene.skView)
        
        scene.skView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            scene.skView.centerXAnchor.constraint(equalTo: container.centerXAnchor),
            scene.skView.centerYAnchor.constraint(equalTo: container.centerYAnchor),
            scene.skView.widthAnchor.constraint(equalTo: container.widthAnchor),
            scene.skView.heightAnchor.constraint(equalTo: container.heightAnchor)
        ])
        
    }
    
    /// Misc.
    
    public static func load(customFont: String, withExtension ext: String = "ttf") {
        let fontURL = Bundle.main.url(forResource: customFont, withExtension: ext)
        CTFontManagerRegisterFontsForURL(fontURL! as CFURL, CTFontManagerScope.process, nil)
    }
}



public class CanvasLiveViewController : LiveViewController {
    public init(context: PlaygroundContextProtocol) {
        LiveViewController.contentPresentation = context.presentationMode
        super.init(nibName: nil, bundle: nil)
        
        classesToRegister = context.proxyClasses
        self.lifeCycleDelegates = [audioController, Canvas.scene]
        self.contentView = Canvas.container
        
        if context.capabilities.contains(.backgroundMusic) {
            let audioButton = AudioBarButton()
            audioButton.toggleBackgroundAudioOnly = true
            addBarButton(audioButton)
        }
    }

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