//#-hidden-code
//
//  See LICENSE folder for this template’s licensing information.
//
//  Abstract:
//  The Swift file containing the source code edited by the user of this playground book.
//
import SwiftUI
import PlaygroundSupport
import Foundation
import AVFoundation
import UIKit

let page = PlaygroundPage.current
page.needsIndefiniteExecution = true

let 🔳 = 0
let 🟥 = 1
let 🟩 = 2
let 🟦 = 3
let 🟨 = 4
let 🟪 = 5
let r = [  0.0,   1.0,   0.0,   0.0,   1.0,   1.0]
let g = [  0.0,   0.0,   1.0,   0.0,   1.0,   0.0]
let b = [  0.0,   0.0,   0.0,   1.0,   0.0,   1.0]
var myColor = 🟥

func color(_ t: Int) {
    if(t >= 0 && t < 6) {
        myColor = t
    } else {
        PlaygroundPage.current.assessmentStatus = .fail(hints: ["color()の引数に範囲外の値が指定されています。color()の括弧内には0〜6の整数型(Int)の数値を入れてください。"], solution: nil)
    }
}

let numberOfSamples: Int = 1

struct ContentView: View {
    // 1
    @ObservedObject private var mic = MicrophoneMonitor(numberOfSamples: numberOfSamples)

    private func normalize(value: Float) -> Double {
        let level = max(0.2, value + 50.0) / 2.0 // between 0.1 and 25
        return Double(level / 25.0)
    }
    
    // 2

//#-end-hidden-code
/*: some text
##  🗺カリオンの塔
iPadを音で反応する明かりにしよう！\
🔸マイクの音のボリュームに応じて、画面の色が変化するプログラムになっています。\
🔸色の変更と音量レベルの調整をして、カリオンの塔をイルミネーションしよう！

 * Important:
長時間の実行ができるように実行画面の［メーターボタン］を押して、”結果”を有効にするスイッチを[OFF]にしてください。
---
*/
//#-code-completion(everything, hide)
//#-code-completion(identifier, show, 🟥, 🟩, 🟦, 🟨, 🟪)
//#-editable-code
//ここからプログラムです。
var body: some View {
    VStack {
        Rectangle()
            .fill(.red)  // 図形の塗りつぶしに使うViewを指定
            .opacity(normalize(value: mic.soundLevel))
            .frame(width:UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
        }.onAppear() { color(🟥) }
    }
}
//#-end-editable-code
//#-hidden-code

class MicrophoneMonitor: ObservableObject {
    
    // 1
    private var audioRecorder: AVAudioRecorder
    private var timer: Timer?
    
    private var currentSample: Int
    private let numberOfSamples: Int
    
    // 2
    @Published public var soundSamples: [Float]
    @Published public var soundLevel: Float
    
    init(numberOfSamples: Int) {
        self.numberOfSamples = numberOfSamples // In production check this is > 0.
        self.soundSamples = [Float](repeating: .zero, count: numberOfSamples)
        self.currentSample = 0
        self.soundLevel = 0.0
        
        // 3
        let audioSession = AVAudioSession.sharedInstance()
        if audioSession.recordPermission != .granted {
            audioSession.requestRecordPermission { (isGranted) in
                if !isGranted {
                    fatalError("You must allow audio recording for this demo to work")
                }
            }
        }
        
        // 4
        let url = URL(fileURLWithPath: "/dev/null", isDirectory: true)
        let recorderSettings: [String:Any] = [
            AVFormatIDKey: NSNumber(value: kAudioFormatAppleLossless),
            AVSampleRateKey: 44100.0,
            AVNumberOfChannelsKey: 1,
            AVEncoderAudioQualityKey: AVAudioQuality.min.rawValue
        ]
        
        // 5
        do {
            audioRecorder = try AVAudioRecorder(url: url, settings: recorderSettings)
            try audioSession.setCategory(.playAndRecord, mode: .default, options: [])
            
            startMonitoring()
        } catch {
            fatalError(error.localizedDescription)
        }
    }
    
    // 6
    private func startMonitoring() {
        audioRecorder.isMeteringEnabled = true
        audioRecorder.record()
        timer = Timer.scheduledTimer(withTimeInterval: 0.05, repeats: true, block: { (timer) in
            // 7
            self.audioRecorder.updateMeters()
            self.soundSamples[self.currentSample] = self.audioRecorder.averagePower(forChannel: 0)
            self.currentSample = (self.currentSample + 1) % self.numberOfSamples
            self.soundLevel = self.audioRecorder.averagePower(forChannel: 0)
        })
    }
    
    // 8
    deinit {
        timer?.invalidate()
        audioRecorder.stop()
    }
}

PlaygroundPage.current.setLiveView(ContentView())



//if( PlaygroundPage.current.assessmentStatus == nil ){
//    PlaygroundPage.current.assessmentStatus = .pass(message: "😄実行しました!")
//}

// Add this to the top of our ContentView.swift file.


//#-end-hidden-code
