package model;

import workers.MachineWorker;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.File;
import java.nio.file.Files;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

@XmlRootElement(name = "Config")
public class SOMConfig {


    // important Paths
    @XmlElement(name = "PICTURES_PATH")
    public static final File PICTURES_PATH = new File("images");
    @XmlElement(name = "UPLOAD_PATH")
    public static final String UPLOAD_PATH = getEventPicDir();
    // The Box's ID
    // Todo Throw out!! or by MAC Adress
    @XmlElement(name = "BOX_ID")
    public static final String BOX_ID = MachineWorker.getHostName();
    // Number of pictures in series mode
    @XmlElement(name = "SERIES_COUNTER")
    public static final int SERIES_COUNTER = 4;
    // Seconds before image is taken
    @XmlElement(name = "COUNTDOWN_COUNTER")
    public static final int COUNTDOWN_COUNTER = 3;
    // Images per Page in the Gallery
    public static final int IMAGES_PER_PAGE = 9;
    // Limot of Parallel Uploads
    public static final int PARALLEL_UPLOADS = 10;
    // Cloud Credentials
    public static final String CLOUD_CREDENTIALS = "upload:geheim";
    // Make the Scaling Algorithm switchable
    public static final int SCALING_GRAPHICS_2D = 0;
    public static final int SCALING_IMAGE_ICON = 1;
    public static final int SCALING_JAVAFX = 2;
    public static final int SCALING_ALGORITHM = SCALING_GRAPHICS_2D;
    // Path to configfile
    //TODO Resource??
    private static final File configfile = new File(SOMLayout.class.getResource("/config/config.xml").getFile());
    // Instance
    private static SOMConfig config = null;


    // Constructor
    private SOMConfig() {
        // TODO fix readConfig
        // readConfig();

        // get the default Displays' dimensions
        System.out.println("Screen Dimensions: " + SOMLayout.screenWidth + "x" + SOMLayout.screenHeight);
    }

    // Instance
    public static SOMConfig getInstance() {
        // Singleton Pattern
        if (config == null) {
            config = new SOMConfig();
        }
        return config;
    }

    /**
     * Gets the Directory for the Event and Creates the Folders
     *
     * @return
     */
    public static String getEventPicDir() {
        // get current Date in String for Upload-dir
        Calendar cal = Calendar.getInstance();
        DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
        String timeString = df.format(cal.getTime());

        File picturesPath = SOMConfig.PICTURES_PATH;

//        File eventPicDir = new File(picturesPath.toString() + "/" + timeString
//                + "/" + MachineWorker.getHostName());
        // TODO catch possible fail
//        eventPicDir.mkdirs();

        String eventPicDir = picturesPath.toString() + "/" + timeString
                + "/" + MachineWorker.getHostName();

        return eventPicDir;
    }

    // Write Config
    private void writeConfig() {
        try {

            // TODO catch possible fail
            configfile.getParentFile().mkdirs();

            JAXBContext jaxbContext = JAXBContext.newInstance(SOMConfig.class);
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

            // output pretty printed
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            jaxbMarshaller.marshal(this, configfile);
            jaxbMarshaller.marshal(this, System.out);

        } catch (JAXBException e) {
            e.printStackTrace();
        }

    }

    // Read Config
    public void readConfig() {
        try {

            if (Files.exists(configfile.toPath())) {

                JAXBContext jaxbContext = JAXBContext
                        .newInstance(SOMConfig.class);

                Unmarshaller jaxbUnmarshaller = jaxbContext
                        .createUnmarshaller();
                config = (SOMConfig) jaxbUnmarshaller.unmarshal(configfile);

                System.out.println();
            } else {
                this.writeConfig();
            }
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }

    // return the current Timestamp
    public long getCurrentTimestamp() {
        // 1) create a java calendar instance
        Calendar calendar = Calendar.getInstance();

        // 2) get a java.util.Date from the calendar instance.
        // this date will represent the current instant, or "now".
        java.util.Date now = calendar.getTime();

        // 3) a java current time (now) instance
        java.sql.Timestamp c = new java.sql.Timestamp(now.getTime());
        return c.getTime();
    }
}