package workers;

//import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

// import org.cups4j.PrintJob;

/**
 *
 */
public class PrintWorker implements Runnable {
    private static Thread queueWorker = null;
    private static PrintWorker instance;
    // TODO Add Printer Model Code
    private final List<File> waitQueue = new ArrayList<File>();
    private final List<File> workQueue = new ArrayList<File>();
    private final File printcountfile = new File("src/main/resources/config/printcount");
    private File imagetransfer = null;
    private int copiestransfer = 0;
    private int printcount = getPrintcount();

    /**
     *
     */
    private PrintWorker(int copies, File image) {

        this.imagetransfer = image;
        this.copiestransfer = copies;

        if (queueWorker == null) {
            queueWorker = new Thread(this);
            queueWorker.setName("SOMPrintQueue");
            queueWorker.start();
        }
    }

    /**
     * @param copies
     * @param image
     */
    public static void print(int copies, File image) {

        if (instance == null) {
            instance = new PrintWorker(copies, image);
        } else {
            instance.addPrint(copies, image);
        }
    }

    /**
     *
     */
    public static void resumePrint() {
        synchronized (queueWorker) {
            System.out.println("resume print thread");
            queueWorker.notify();
        }
    }

    public Thread getQueueWorker() {
        return queueWorker;
    }

    private void addPrint(int copies, File image) {

        // add to Print Queue
        for (int i = 0; i < copies; i++) {
            waitQueue.add(image);
        }
    }

    /**
     *
     */
    private void workQueue() {
        if (printcountfile.exists()) {
            printcount = getPrintcount();
        }
        // Refresh working queue (if there is anything to refresh)
        if (waitQueue.size() != 0) {
            for (File image :
                    waitQueue) {
                // switch files over from wait to work
                workQueue.add(image);
//                waitQueue.remove(image);
            }
            // TODO Recursion may do this
            waitQueue.removeAll(waitQueue);
        }

        // work all the workQueue Files
        if (workQueue.size() != 0) {
            for (File image :
                    workQueue) {

                // Halt the Process if anything is empty
                if (printcount % 36 == 0) {
                    // Check Paper (18 per Package)
//                    MainFrame mf = MainFrame.getInstance();
//                    JPanel cp = (JPanel) mf.getContentPane();
//                    CardLayout cl = (CardLayout) cp.getLayout();
//
//                    WarnPanel.getInstance().setTextText("Bitte Papier und Farbe wechseln");

//                    cl.show(cp, "warn");

                    try {
                        synchronized (queueWorker) {
                            System.out.println("pause print thread");
                            queueWorker.wait();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    // Todo set printcount to 0

                } else if (printcount % 18 == 0) {
//                    // Check Ink   (36 per Package)
//                    MainFrame mf = MainFrame.getInstance();
//                    JPanel cp = (JPanel) mf.getContentPane();
//                    CardLayout cl = (CardLayout) cp.getLayout();
//
//                    WarnPanel.getInstance().setTextText("Bitte Papier wechseln");
//                    cl.show(cp, "warn");

                    try {
                        synchronized (queueWorker) {
                            System.out.println("pause print thread");
                            queueWorker.wait();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                sendToPrinter(image);
                System.out.println("Drucke " + printcount);

                // Timeout in Milliseconds
                try {
                    System.out.println("Going to Sleep");
                    Thread.sleep(65000);
                    System.out.println("Waking Up");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //remove the just printed File from Queue
//                workQueue.remove(image);
                addPrintcount();
            }

            workQueue.removeAll(workQueue);

            workQueue();

        }

        // Recurse
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        workQueue();
    }


    /**
     * @param image
     */
    private void sendToPrinter(File image) {
        // Bild in Druckwarteschlange einfügen
        String command = "lp " + image.toString();
        System.out.println(command);

        try {
            Process child = Runtime.getRuntime().exec(command);
            System.out.println(child.getErrorStream().toString());
            addPrintcount();
        } catch (IOException e) {
            System.out.println("Print Failed");
            e.printStackTrace();
        }
    }

    /**
     *
     */
    private void addPrintcount() {
        // Count up the prints
        printcount++;
        // Write printcount to File (for recovery)
//        try {
//            FileUtils.writeStringToFile(printcountfile, Integer.toString(printcount));
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
    }

    /**
     * @return
     */
    private int getPrintcount() {
        if (printcount == 0) {
            if (printcountfile.exists()) {
                System.out.println("printcount is 0, Prontcountfile exists");
//                try {
//                    // read printcount File
//                    printcount = Integer.parseInt(FileUtils.readFileToString(printcountfile));
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
            } else {
                printcount = 0;
            }
        }
        return printcount;
    }

    /**
     *
     */
    public void run() {
        // TODO run implementation

        addPrint(copiestransfer, imagetransfer);

        // work down print Queue
        workQueue();

    }
}
