#include <QSettings>
#include "ConfigData.h"

#define ORGANIZATION "diybookscanner"
#define APPLICATION  "book-scanner"

ConfigData * ConfigData::config_instance = NULL;

ConfigData *
ConfigData::GetConfig() {
   if (config_instance == NULL) {
      config_instance = new ConfigData;
   }
   return config_instance;
}

ConfigData::ConfigData() {
   QSettings qs(ORGANIZATION, APPLICATION);
   uk1104_vendor = qs.value("UK1104Vendor", "04d8").toString();
   uk1104_model = qs.value("UK1104Model", "fc73").toString();
   uk1104_id_code = qs.value("UK1104IdCode", "00").toString();
   ReadStringList(qs, "UK1104Initialize", uk1104_initialize);
   ReadStringList(qs, "UK1104TurnOnLights", uk1104_turn_on_lights);
   ReadStringList(qs, "UK1104TurnOffLights", uk1104_turn_off_lights);
   ReadStringList(qs, "UK1104TurnOnUsb", uk1104_turn_on_USB);
   ReadStringList(qs, "UK1104TurnOffUsb", uk1104_turn_off_USB);
   uk1104_poll_input = qs.value("UK1104PollInput", false).toBool();
   uk1104_input_channel = qs.value("UK1104InputChannel", 1).toInt();
   uk1104_button_pressed_value = qs.value("UK1104ButtonPressedValue", 0).toInt();
   left_camera_vendor = qs.value("LeftCameraVendor", "04a9").toString();
   left_camera_model = qs.value("LeftCameraModel", "").toString();
   left_camera_serial = qs.value("LeftCameraSerial", "").toString();
   left_camera_src_directory =
      qs.value("LeftCameraSrcDirectory", "/store_00010001/DCIM/100CANON").
         toString();
   ReadStringList(qs, "LeftCameraImageFilters", left_camera_image_filters);
   right_camera_vendor = qs.value("RightCameraVendor", "04a9").toString();
   right_camera_model = qs.value("RightCameraModel", "").toString();
   right_camera_serial = qs.value("RightCameraSerial", "").toString();
   right_camera_src_directory =
      qs.value("RightCameraSrcDirectory", "/store_00010001/DCIM/100CANON").
         toString();
   ReadStringList(qs, "RightCameraImageFilters", right_camera_image_filters);
   destination_directory = qs.value("DestinationDirectory", "").toString();
   left_camera_subdir = qs.value("LeftCameraSubdir", "left").toString();
   right_camera_subdir = qs.value("RightCameraSubdir", "right").toString();
   preference_independent_buttons =
      qs.value("PreferenceIndependentButtons", true).toBool();
   preference_image_preview_size.setWidth(
      qs.value("PreferenceImagePreviewWidth", 320).toInt());
   preference_image_preview_size.setHeight(
      qs.value("PreferenceImagePreviewHeight", 240).toInt());
   ReadProgram(qs, "LightsProgram", lights_prog);
   ReadProgram(qs, "CameraProgram", cam_prog);
   ReadProgram(qs, "DownloadProgram", download_prog);
   download_const_tenths_of_seconds =
      qs.value("DownloadConstTenthsOfSecond", 0).toInt();
   download_one_image_tenths_of_seconds =
      qs.value("DownloadOneImageTenthsOfSecond", 0).toInt();
}

ConfigData::~ConfigData() {
}

void
ConfigData::SaveConfigData() {
   QSettings qs(ORGANIZATION, APPLICATION);
   qs.setValue("UK1104Vendor", uk1104_vendor);
   qs.setValue("UK1104Model", uk1104_model);
   qs.setValue("UK1104IdCode", uk1104_id_code);
   SaveStringList(qs, "UK1104Initialize", uk1104_initialize);
   SaveStringList(qs, "UK1104TurnOnLights", uk1104_turn_on_lights);
   SaveStringList(qs, "UK1104TurnOffLights", uk1104_turn_off_lights);
   SaveStringList(qs, "UK1104TurnOnUsb", uk1104_turn_on_USB);
   SaveStringList(qs, "UK1104TurnOffUsb", uk1104_turn_off_USB);
   qs.setValue("UK1104PollInput", uk1104_poll_input);
   qs.setValue("UK1104InputChannel", uk1104_input_channel);
   qs.setValue("UK1104ButtonPressedValue", uk1104_button_pressed_value);
   qs.setValue("LeftCameraVendor", left_camera_vendor);
   qs.setValue("LeftCameraModel", left_camera_model);
   qs.setValue("LeftCameraSerial", left_camera_serial);
   qs.setValue("LeftCameraSrcDirectory", left_camera_src_directory);
   SaveStringList(qs, "LeftCameraImageFilters", left_camera_image_filters);
   qs.setValue("RightCameraVendor", right_camera_vendor);
   qs.setValue("RightCameraModel", right_camera_model);
   qs.setValue("RightCameraSerial", right_camera_serial);
   qs.setValue("RightCameraSrcDirectory", right_camera_src_directory);
   SaveStringList(qs, "RightCameraImageFilters", right_camera_image_filters);
   qs.setValue("DestinationDirectory", destination_directory);
   qs.setValue("LeftCameraSubdir", left_camera_subdir);
   qs.setValue("RightCameraSubdir", right_camera_subdir);
   qs.setValue("PreferenceIndependentButtons", preference_independent_buttons);
   qs.setValue("PreferenceImagePreviewWidth",
               preference_image_preview_size.width());
   qs.setValue("PreferenceImagePreviewHeight",
               preference_image_preview_size.height());
   SaveProgram(qs, "LightsProgram", lights_prog);
   SaveProgram(qs, "CameraProgram", cam_prog);
   SaveProgram(qs, "DownloadProgram", download_prog);
   qs.setValue("DownloadConstTenthsOfSecond",
               download_const_tenths_of_seconds);
   qs.setValue("DownloadOneImageTenthsOfSecond",
               download_one_image_tenths_of_seconds);
}

QString
ConfigData::UK1104Vendor() {
   return uk1104_vendor;
}

QString
ConfigData::UK1104Model() {
   return uk1104_model;
}

QString
ConfigData::UK1104IdCode() {
   return uk1104_id_code;
}

QStringList
ConfigData::UK1104Initialize() {
   return uk1104_initialize;
}

QStringList
ConfigData::UK1104TurnOnLights() {
   return uk1104_turn_on_lights;
}

QStringList
ConfigData::UK1104TurnOffLights() {
   return uk1104_turn_off_lights;
}

QStringList
ConfigData::UK1104TurnOnUSB() {
   return uk1104_turn_on_USB;
}

QStringList
ConfigData::UK1104TurnOffUSB() {
   return uk1104_turn_off_USB;
}

bool
ConfigData::UK1104PollInput() {
   return uk1104_poll_input;
}

int
ConfigData::UK1104InputChannel() {
   return uk1104_input_channel;
}

int
ConfigData::UK1104ButtonPressedValue() {
   return uk1104_button_pressed_value;
}

QString
ConfigData::LeftCameraVendor() {
   return left_camera_vendor;
}

QString
ConfigData::LeftCameraModel() {
   return left_camera_model;
}

QString
ConfigData::LeftCameraSerial() {
   return left_camera_serial;
}

QString
ConfigData::LeftCameraSrcDirectory() {
   return left_camera_src_directory;
}

QStringList
ConfigData::LeftCameraImageFilters() {
   return left_camera_image_filters;
}

QString
ConfigData::RightCameraVendor() {
   return right_camera_vendor;
}

QString
ConfigData::RightCameraModel() {
   return right_camera_model;
}

QString
ConfigData::RightCameraSerial() {
   return right_camera_serial;
}

QString
ConfigData::RightCameraSrcDirectory() {
   return right_camera_src_directory;
}

QStringList
ConfigData::RightCameraImageFilters() {
   return right_camera_image_filters;
}

QString
ConfigData::DestinationDirectory() {
   return destination_directory;
}

QString
ConfigData::LeftCameraSubdir() {
   return left_camera_subdir;
}

QString
ConfigData::RightCameraSubdir() {
   return right_camera_subdir;
}

bool
ConfigData::PreferenceIndependentButtons() {
   return preference_independent_buttons;
}

QSize
ConfigData::PreferenceImagePreviewSize() {
   return preference_image_preview_size;
}

ProgramEntryList
ConfigData::LightsProgram() {
   return lights_prog;
}

ProgramEntryList
ConfigData::CameraProgram() {
   return cam_prog;
}

ProgramEntryList
ConfigData::DownloadProgram() {
   return download_prog;
}

int
ConfigData::DownloadConstTenthsOfSecond() {
   return download_const_tenths_of_seconds;
}

int
ConfigData::DownloadOneImageTenthsOfSecond() {
   return download_one_image_tenths_of_seconds;
}

void
ConfigData::SaveStringList(QSettings & qs, QString name, QStringList & vals) {
   qs.beginWriteArray(name);
   for (int i = 0; i < vals.size(); ++i) {
      qs.setArrayIndex(i);
      qs.setValue("val", vals.at(i));
   }
   qs.endArray();
}

void
ConfigData::ReadStringList(QSettings & qs, QString name, QStringList & vals) {
   vals.clear();
   int size = qs.beginReadArray(name);
   for (int i = 0; i < size; ++i) {
      qs.setArrayIndex(i);
      vals << qs.value("val").toString();
   }
   qs.endArray();
}

void
ConfigData::SaveProgram(QSettings & qs, QString name, ProgramEntryList & vals) {
   qs.beginWriteArray(name);
   for (int i = 0; i < vals.size(); ++i) {
      qs.setArrayIndex(i);
      qs.setValue("time", vals.at(i).timespec);
      qs.setValue("action", vals.at(i).actionspec);
   }
   qs.endArray();
}

void
ConfigData::ReadProgram(QSettings & qs, QString name, ProgramEntryList & vals) {
   vals.clear();
   int size = qs.beginReadArray(name);
   for (int i = 0; i < size; ++i) {
      qs.setArrayIndex(i);
      ProgramEntry pe;
      pe.timespec = qs.value("time").toString();
      pe.actionspec = qs.value("action").toString();
      vals << pe;
   }
   qs.endArray();
}
