package com.jpsoft.shinestar.modules.common.utils.Generator;

import cn.hutool.captcha.ICaptcha;
import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

/**
 * @author 墨鱼_mo
 * @date 2019-8-8 15:27
 */

public abstract class AbstractCaptchaA implements ICaptcha {
    private static final long serialVersionUID = 3180820918087507254L;
    protected int width;
    protected int height;
    protected int interfereCount;
    protected Font font;
    protected String code;
    protected byte[] imageBytes;
    protected CodeGenerator generator;
    protected Color background;

    public AbstractCaptchaA(int width, int height, int codeCount, int interfereCount) {
        this(width, height, new RandomGeneratorA(codeCount), interfereCount);
    }

    public AbstractCaptchaA(int width, int height, CodeGenerator generator, int interfereCount) {
        this.width = 100;
        this.height = 37;
        this.interfereCount = 15;
        this.width = width;
        this.height = height;
        this.generator = generator;
        this.interfereCount = interfereCount;
        this.font = new Font("Courier", 0, (int) ((double) this.height * 0.75D));
        this.createCode();
    }

    public void createCode() {
        this.generateCode();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ImgUtil.writePng(this.createImage(this.code), out);
        this.imageBytes = out.toByteArray();
    }

    protected void generateCode() {
        this.code = this.generator.generate();
    }

    protected abstract Image createImage(String var1);

    public String getCode() {
        return this.code;
    }

    public boolean verify(String userInputCode) {
        return this.generator.verify(this.code, userInputCode);
    }

    public void write(String path) throws IORuntimeException {
        this.write(FileUtil.touch(path));
    }

    public void write(File file) throws IORuntimeException {
        try {
            OutputStream out = FileUtil.getOutputStream(file);
            Throwable var3 = null;

            try {
                this.write((OutputStream) out);
            } catch (Throwable var13) {
                var3 = var13;
                throw var13;
            } finally {
                if (out != null) {
                    if (var3 != null) {
                        try {
                            out.close();
                        } catch (Throwable var12) {
                            var3.addSuppressed(var12);
                        }
                    } else {
                        out.close();
                    }
                }

            }

        } catch (IOException var15) {
            throw new IORuntimeException(var15);
        }
    }

    public void write(OutputStream out) {
        IoUtil.write(out, false, this.imageBytes);
    }

    public BufferedImage getImage() {
        if (null == this.imageBytes) {
            this.createCode();
        }

        return ImgUtil.read(new ByteArrayInputStream(this.imageBytes));
    }

    public String getImageBase64() {
        return Base64.encode(this.imageBytes);
    }

    public void setFont(Font font) {
        this.font = font;
    }

    public CodeGenerator getGenerator() {
        return this.generator;
    }

    public void setGenerator(CodeGenerator generator) {
        this.generator = generator;
        this.createCode();
    }

    public void setBackground(Color background) {
        this.background = background;
    }
}

