package com.bomostory.sceneeditmodule

import android.content.Context
import android.graphics.*
import com.bomostory.pdfexport.PdfBookWriter
import com.bomostory.pdfexport.StandardPdfWriter
import com.bomostory.sceneeditmodule.basicdata.Project
import com.example.tfat.myapplication.R
import io.reactivex.Observable
import java.io.File

object PdfMaker {
    fun makeStandard(context: Context, project: Project, file: File): Observable<Float> {
        return Observable.create { emitter ->
            val total = (2 + project.story?.scenes?.size!!).toFloat()
            var progress = 0
            val width = 1920
            val height = 1080
            val coverWidth = width / 2
            emitter.onNext(progress++ / total)
            val front = drawFrontCover(coverWidth, height, project.name ?: "")
            emitter.onNext(progress++ / total)
            val back = drawBackCover(context, coverWidth, height)
            emitter.onNext(progress++ / total)
            val standardPdfWriter = StandardPdfWriter(file, front, back)
            project.story?.scenes?.forEach {
                val bitmap = SceneDrawer.drawScene(it, 0, width, height) ?: return@forEach
                standardPdfWriter.addImage(bitmap)
                emitter.onNext(progress++ / total)
            }
            standardPdfWriter.finish()
            emitter.onComplete()
        }
    }

    fun makeBooklet(context: Context, project: Project, file: File): Observable<Float> {
        return Observable.create { emitter ->
            val total = (2 + project.story?.scenes?.size!!).toFloat()
            var progress = 0
            val width = 1920 / 2
            val height = 1080
            val name = project?.name ?: ""
            val author = project?.author ?: ""
            emitter.onNext(progress++ / total)
            /** front **/
            val front = drawFrontCover(width, height, name)
            emitter.onNext(progress++ / total)
            /** back **/
            val back = drawBackCover(context, width, height)
            emitter.onNext(progress++ / total)
            /** pages **/
            val pdfBookWriter = PdfBookWriter(file, front, back)
            project.story?.scenes?.forEach {
                val bitmap = SceneDrawer.drawScene(it, 0, width, height) ?: return@forEach
                pdfBookWriter.addImage(bitmap)
                emitter.onNext(progress++ / total)
            }
            pdfBookWriter.finish()
            emitter.onComplete()
        }
    }

    private fun drawFrontCover(width: Int, height: Int, name: String): Bitmap {
        val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
            color = Color.WHITE
            textSize = 100f
            textAlign = Paint.Align.CENTER
            flags += Paint.FAKE_BOLD_TEXT_FLAG
        }
        return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444).apply {
            Canvas(this).apply {
                drawColor(Color.parseColor("#faa600"))
                val marginBottom = height / 20
                val rect = Rect(0, height - height / 3 - marginBottom, width, height - marginBottom)
                val p = Paint(Paint.ANTI_ALIAS_FLAG).apply {
                    color = Color.parseColor("#66ffffff")
                    style = Paint.Style.FILL_AND_STROKE
                }
                drawRect(rect, p)
                drawText(name, rect.centerX().toFloat(), rect.centerY().toFloat(), paint)
            }
        }
    }

    private fun drawBackCover(context: Context, width: Int, height: Int): Bitmap {
        return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444).apply {
            Canvas(this).apply {
                drawColor(Color.parseColor("#faa600"))
                val drawable = context.getDrawable(R.drawable.ic_logo_full_white)
                val marginBottom = this.height / 10
                val w = this.width / 3
                val scale = w.toFloat() / drawable.intrinsicWidth.toFloat()
                val h = drawable.intrinsicHeight * scale
                val left = (this.width - w) / 2
                val top = (this.height - h) - marginBottom
                val right = (this.width + w) / 2
                val bottom = (this.height) - marginBottom
                drawable.setBounds(left, top.toInt(), right, bottom)
                drawable.draw(this)
            }
        }
    }
}