//#-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 PlaygroundSupport
import AudioToolbox
import Foundation
import Network
import UIKit

let page = PlaygroundPage.current
page.needsIndefiniteExecution = true

let 🔳 = 0
let 🟥 = 1
let 🟩 = 2
let 🟦 = 3
let 🟨 = 4
let 🟪 = 5

func vprint(_ str: String) {
   if let proxy1 = page.liveView as? PlaygroundRemoteLiveViewProxy {
       let message: PlaygroundValue = .string(str)
       proxy1.send(message)
   }
}

func send(_ str: String) {
    if let proxy1 = page.liveView as? PlaygroundRemoteLiveViewProxy {
        let message: PlaygroundValue = .string(str)
        proxy1.send(message)
    }
}

func clear() {
    Thread.sleep(forTimeInterval: 0.5)
    send("clear")
}

func mark(_ title: String, _ latitude: Double, _ longitude: Double) {
    if(latitude < 0.0 || longitude < 0.0) {
        PlaygroundPage.current.assessmentStatus = .fail(hints: ["mark()の引数に範囲外の値が指定されています。緯度,経度の２つの値は0.0より大きい必要があります。"], solution: nil)
    } else {
        Thread.sleep(forTimeInterval: 0.5)
        send("mark "+title+" "+latitude.description+" "+longitude.description)
    }
}

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

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


//annotationリクエスト後に送られるビューの写真を受信した場合の処理
let proxy2 = page.liveView as? PlaygroundRemoteLiveViewProxy
class pgListener: PlaygroundRemoteLiveViewProxyDelegate {
    func remoteLiveViewProxy(_ remoteLiveViewProxy: PlaygroundRemoteLiveViewProxy,received message: PlaygroundValue) {
        if case let .string(geoStr) = message {
            //位置情報を送信する関数を呼びだす
            sendGeoPointData(geostring: geoStr)
            return
        }
    }
    func remoteLiveViewProxyConnectionClosed(_ remoteLiveViewProxy: PlaygroundRemoteLiveViewProxy) {
        //コネクション切断時の処理
    }
}
let pglistener = pgListener()
proxy2?.delegate = pglistener
send("clear") //ピンを全削除
send("enable")//コールアウト無効

clear() //ピンを全削除

//#-end-hidden-code
/*: some text
##  🗺2️⃣クライアント側
　このプログラムは、地図サーバーに位置情報を送信するためのものです。\
　ライブビューに表示されている地図を長押しすると、その場所にマーカーを追加できます。\
　マーカーをタップして吹き出しを表示して、吹き出しをタップすると、サーバーに位置情報を送る事ができます。

 * Note:
 このプログラムはサーバーのIPアドレスを変更するだけで動作します。\
 サーバー側のプログラムを実行した後で実行してください。
 ---
 * Important:
 地図のタイプは0〜4まで指定できますが、を3D表示にするとSwiftPlaygroundsアプリが動作しなくなる時があります。
 ---
 */
//#-code-completion(everything, hide)

//地図のタイプ
type(0)
//受信中のイメージデータ
private var receivedImageData: Data?
//🖍️サーバーのIPアドレス
private var host = NWEndpoint.Host("192.168.0.62")
//ポート番号
private var port = NWEndpoint.Port(rawValue: 50000)!

// マーカーの吹き出しをタップされた時に呼び出される
func sendGeoPointData(geostring: String) {
    //コネクションを開始する。
    let connection = NWConnection(host: host, port: port, using: .tcp)
    connection.stateUpdateHandler = { newState in
    }
    connection.start(queue: .main)
    //位置情報を相手に送信する。
    let geoStr = geostring
    let geoData: Data? = geoStr.data(using: .utf8)
    connection.send(content: geoData, completion: .contentProcessed { error in
        if let error = error {
            vprint("データの送信に失敗しました.: \(error.localizedDescription)")
        }
        connection.cancel()
    })
}
