//
//  See LICENSE folder for this template’s licensing information.
//
//  Abstract:
//  A source file which is part of the auxiliary module named "BookCore".
//  Provides the implementation of the "always-on" live view.
//

import Foundation
import UIKit
import PlaygroundSupport
import PhotosUI
import PDFKit

public class PDFandDrawViewController: UIViewController, PlaygroundLiveViewMessageHandler, PlaygroundLiveViewSafeAreaContainer {
    
    private let expLabel = UILabel()
    private let drawView = DrawView(frame: CGRect(x:0, y:0, width:200, height:300))
    private let textView = UITextView()
    private var vstring = String()
    private var textColor = UIColor()
    private var pdfDocument: PDFDocument!
    private var pdfUrl: URL?
    private let pdfView = PDFView()
    private let clearButton = UIButton()
    private let sendButton = UIButton()
    
    
    override public func viewDidLoad() {
        super.viewDidLoad()

        //view.backgroundColor = .systemCyan
        view.backgroundColor = .lightGray
        // disable auto layout
        view.translatesAutoresizingMaskIntoConstraints = false

        // PDFViewを配置
        //let pdfView = PDFView(frame: self.view.frame)
        self.view.addSubview(pdfView)
        //PDF表示用のimageビューを配置
        pdfView.isUserInteractionEnabled = true
        pdfView.translatesAutoresizingMaskIntoConstraints  = false
        pdfView.backgroundColor = UIColor(.gray)
        pdfView.topAnchor.constraint(equalTo: liveViewSafeAreaGuide.topAnchor, constant: 0).isActive = true
        pdfView.bottomAnchor.constraint(equalTo: liveViewSafeAreaGuide.bottomAnchor, constant: 0).isActive = true
        pdfView.leadingAnchor.constraint(equalTo: liveViewSafeAreaGuide.leadingAnchor, constant: 0).isActive = true
        pdfView.trailingAnchor.constraint(equalTo: liveViewSafeAreaGuide.trailingAnchor, constant: 0).isActive = true
        // PDFビューを設定
        pdfView.autoScales = true
        //pdfView.displaysPageBreaks = false
        pdfView.displayMode = .singlePageContinuous
        pdfView.displayDirection = .horizontal
        pdfView.usePageViewController(true)
        pdfView.isHidden = false
        // PDFをロード
        if let path = Bundle.main.path(forResource: "explane2", ofType: "pdf") {
            pdfUrl = URL(fileURLWithPath: path)
            print("url = \(path)")
        }
        pdfView.document = PDFDocument(url: pdfUrl!)
        
        //説明ラベルを設定
        expLabel.text = "コードを実行している状態で、数字を１つ描いて［画像をコードに渡す］ボタンを押してしてください。"
        expLabel.numberOfLines = 0 //折り返し
        view.addSubview(expLabel)
        expLabel.isUserInteractionEnabled = true
        expLabel.layer.cornerRadius = 10
        expLabel.translatesAutoresizingMaskIntoConstraints  = false
        expLabel.topAnchor.constraint(equalTo: liveViewSafeAreaGuide.topAnchor, constant: 0).isActive = true
        expLabel.bottomAnchor.constraint(equalTo: liveViewSafeAreaGuide.topAnchor, constant: 60).isActive = true
        expLabel.leadingAnchor.constraint(equalTo: liveViewSafeAreaGuide.leadingAnchor, constant: 20).isActive = true
        expLabel.trailingAnchor.constraint(equalTo: liveViewSafeAreaGuide.trailingAnchor, constant: -20).isActive = true
        expLabel.isHidden = true
        
        //手書きビューを配置
        view.addSubview(drawView)
        drawView.isUserInteractionEnabled = true
        drawView.layer.cornerRadius = 10
        drawView.translatesAutoresizingMaskIntoConstraints  = false
        drawView.topAnchor.constraint(equalTo: expLabel.bottomAnchor, constant: 10).isActive = true
        drawView.bottomAnchor.constraint(equalTo: liveViewSafeAreaGuide.bottomAnchor, constant: -160).isActive = true
        drawView.leadingAnchor.constraint(equalTo: liveViewSafeAreaGuide.leadingAnchor, constant: 20).isActive = true
        drawView.trailingAnchor.constraint(equalTo: liveViewSafeAreaGuide.trailingAnchor, constant: -20).isActive = true
        drawView.isHidden = true
        
        //クリア（消しゴム）ボタンの設置
        // ボタンの位置とサイズを設定
        clearButton.frame = CGRect(x:10, y:10, width:50, height:50)
        // タップされたときのaction
        clearButton.addTarget(self,action: #selector(clearButtonTapped), for: .touchUpInside)
        // クリアボタンのタイトルを設定
        let largeConfig = UIImage.SymbolConfiguration(pointSize: 30, weight: .bold, scale: .medium)
        let largeBoldDoc = UIImage(systemName: "trash", withConfiguration: largeConfig)
        clearButton.setImage(largeBoldDoc, for: .normal)
        clearButton.backgroundColor = UIColor(.white)
        clearButton.setTitleColor(UIColor.blue, for: .normal)
        clearButton.layer.cornerRadius = 25
        //clearButton.setTitle("クリア", for:UIControl.State.normal)
        drawView.addSubview(clearButton)
        clearButton.isUserInteractionEnabled = true
        //clearButton.translatesAutoresizingMaskIntoConstraints  = false
        //clearButton.topAnchor.constraint(equalTo: drawView.topAnchor, constant: 10).isActive = true
        //clearButton.leadingAnchor.constraint(equalTo: drawView.trailingAnchor, constant: 20).isActive = true
        clearButton.isHidden = true
        //コードに画像を渡すボタンの設置
        sendButton.frame = CGRect(x:10, y:10, width: 100, height:50)
        // タップされたときのaction
        sendButton.addTarget(self,action: #selector(sendButtonTapped), for: .touchUpInside)
        // 画像を渡すボタンのタイトルを設定
        let largeConfig1 = UIImage.SymbolConfiguration(pointSize: 20, weight: .bold, scale: .medium)
        let largeBoldDoc1 = UIImage(systemName: "paperplane.fill", withConfiguration: largeConfig1)
        sendButton.setImage(largeBoldDoc1, for: .normal)
        sendButton.setTitle("　画像をコードに渡す", for: UIControl.State.normal)
        sendButton.layer.cornerRadius = 10
        // 影
        sendButton.layer.shadowColor = UIColor.black.cgColor
        sendButton.layer.shadowOpacity = 0.8
        sendButton.layer.shadowRadius = 8.0
        sendButton.layer.shadowOffset = CGSize(width: 0.0, height: 1.0)
        
        sendButton.backgroundColor = UIColor(.white)
        sendButton.setTitleColor(UIColor.blue, for: .normal)
        view.addSubview(sendButton)
        sendButton.isUserInteractionEnabled = true
        sendButton.translatesAutoresizingMaskIntoConstraints  = false
        sendButton.translatesAutoresizingMaskIntoConstraints  = false
        sendButton.topAnchor.constraint(equalTo: drawView.bottomAnchor, constant: 10).isActive = true
        sendButton.bottomAnchor.constraint(equalTo: liveViewSafeAreaGuide.bottomAnchor, constant: -80).isActive = true
        sendButton.leadingAnchor.constraint(equalTo: liveViewSafeAreaGuide.leadingAnchor, constant: 20).isActive = true
        sendButton.trailingAnchor.constraint(equalTo: liveViewSafeAreaGuide.trailingAnchor, constant: -20).isActive = true
        sendButton.isHidden = true
        
        //メッセージ表示用のビューを配置
        textView.font = UIFont.monospacedSystemFont(ofSize: 20, weight: .medium)
        textView.isEditable = false
        view.addSubview(textView)
        //textView.textColor = .white
        textView.translatesAutoresizingMaskIntoConstraints  = false
        textView.topAnchor.constraint(equalTo: sendButton.bottomAnchor, constant: 10).isActive = true
        textView.bottomAnchor.constraint(equalTo: liveViewSafeAreaGuide.bottomAnchor, constant: 0).isActive = true
        textView.leadingAnchor.constraint(equalTo: liveViewSafeAreaGuide.leadingAnchor, constant: 20).isActive = true
        textView.trailingAnchor.constraint(equalTo: liveViewSafeAreaGuide.trailingAnchor, constant: -20).isActive = true
        textView.isHidden = true
    }
    @objc func clearButtonTapped()
    {
        drawView.clearImage()
    }
    
    @objc func sendButtonTapped()
    {
        //黒い背景と重ね合わせる処理
        var images: [UIImage] = [UIImage]()
        let bgimg = UIImage(named: "BLKbackground.png") //背景
        images.append(bgimg!)
        if(drawView.image != nil) {
            images.append(drawView.image!)
        }
        
        let sendImage = compositeImages(images: images )
        
        let photoData : Data = sendImage.jpegData(compressionQuality: 1)!
        let message: PlaygroundValue = .data(photoData)
        send(message)
    }
    
    public func liveViewMessageConnectionOpened() {
        // Implement this method to be notified when the live view message connection is opened.
        // The connection will be opened when the process running Contents.swift starts running and listening for messages.
        pdfView.isHidden = true
        expLabel.isHidden = false
        drawView.isHidden = false
        clearButton.isHidden = false
        sendButton.isHidden = false
        textView.isHidden = false
        
    }

    public func liveViewMessageConnectionClosed() {
        // Implement this method to be notified when the live view message connection is closed.
        // The connection will be closed when the process running Contents.swift exits and is no longer listening for messages.
        // This happens when the user's code naturally finishes running, if the user presses Stop, or if there is a crash.
        textView.text = ""
        //pdfView.isHidden = false
        //photoImageView.isHidden = true
        //textView.isHidden = true
    }
    
    public func receive(_ message: PlaygroundValue) {
        // Implement this method to receive messages sent from the process running Contents.swift.
        // This method is *required* by the PlaygroundLiveViewMessageHandler protocol.
        // Use this method to decode any messages sent as PlaygroundValue values and respond accordingly.
        if case let .data(data) = message {
            if !data.isEmpty {
                //photoImageView.image = UIImage(data: data)
                UIView.transition(with: drawView,
                                  duration: 0.75,
                                  options: .transitionFlipFromLeft,
                                  animations: { self.drawView.image = UIImage(data: data) },
                                  completion: nil)
            } else {
                textView.text = textView.text + "dataが空です。\n"
            }
        }
        if case let .string(text) = message {
            textView.text = textView.text + "\(text)\n"
        }
    }
    
    public override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        //PDF表示を小さくしすぎないようにする。
        pdfView.minScaleFactor = pdfView.scaleFactor
        //pdfView.maxScaleFactor = pdfView.scaleFactor
    }
}


public extension UIButton {
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
       super.touchesBegan(touches, with: event)
        touchStartAnimation(p: self)
    }
    
    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesCancelled(touches, with: event)
        touchEndAnimation(p: self)
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesEnded(touches, with: event)
        touchEndAnimation(p: self)
    }
}

func touchStartAnimation(p: UIButton, duration: CGFloat = 0.1){
    UIView.animate(withDuration: duration,
        delay: 0.0,
        options: UIView.AnimationOptions.curveEaseIn,
        animations: {() -> Void in
            p.transform = CGAffineTransform(scaleX: 0.95, y: 0.95);
            p.alpha = 0.7
        },
        completion: nil
    )
}

func touchEndAnimation(p: UIButton, duration: CGFloat = 0.1){
    UIView.animate(withDuration: duration,
        delay: 0.0,
        options: UIView.AnimationOptions.curveEaseIn,
        animations: {() -> Void in
            p.transform = CGAffineTransform(scaleX: 1.0, y: 1.0);
            p.alpha = 1
        },
        completion: nil
    )
}

func compositeImages(images: [UIImage]) -> UIImage {
    var compositeImage: UIImage!
    if images.count > 0 {
        // Get the size of the first image.  This function assume all images are same size
        let size: CGSize = CGSize(width: images[0].size.width, height: images[0].size.height)
        UIGraphicsBeginImageContext(size)
        for image in images {
            let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
            image.draw(in: rect)
        }
        compositeImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
    }
    return compositeImage
}
