/*   **********************************************************************  **
 **   Copyright notice                                                       **
 **                                                                          **
 **   (c) 2003-2006 RSSOwl Development Team                                  **
 **   http://www.rssowl.org/                                                 **
 **                                                                          **
 **   All rights reserved                                                    **
 **                                                                          **
 **   This program and the accompanying materials are made available under   **
 **   the terms of the Eclipse Public License 1.0 which accompanies this     **
 **   distribution, and is available at:                                     **
 **   http://www.rssowl.org/legal/epl-v10.html                               **
 **                                                                          **
 **   A copy is found in the file epl-v10.html and important notices to the  **
 **   license from the team is found in the textfile LICENSE.txt distributed **
 **   in this package.                                                       **
 **                                                                          **
 **   This copyright notice MUST APPEAR in all copies of the file!           **
 **                                                                          **
 **   Contributors:                                                          **
 **     RSSOwl - initial API and implementation (bpasero@rssowl.org)         **
 **                                                                          **
 **  **********************************************************************  */

package net.sourceforge.rssowl.controller.thread;

import net.sourceforge.rssowl.controller.GUI;
import net.sourceforge.rssowl.dao.SettingsSaver;
import net.sourceforge.rssowl.util.GlobalSettings;
import net.sourceforge.rssowl.util.shop.SimpleFileShop;

import java.io.File;
import java.io.IOException;

/**
 * The SettingsManager is responsible to save Settings in a certain interval.
 * Whenever Favorites, Categories or Blogrolls are added, edited or removed, the
 * SettingsManager is told to save Settings next time it checks for the
 * <code>isSaveRequested</code> flag.
 * <p>
 * In addition, the Manager is also looking if the Archive is in need of
 * flushing changes to the disk. The Archive is responsible of persisting the
 * state of News that are marked as read.
 * </p>
 * 
 * @author <a href="mailto:bpasero@rssowl.org">Benjamin Pasero </a>
 * @version 1.2.3
 */
public class SettingsManager extends ExtendedThread {
  private static SettingsManager instance;
  private static final int SLEEP_INTERVAL = 1 * 20 * 1000;
  private boolean isSaveRequested;
  GUI rssOwlGui;

  /**
   * Singleton Instantiation of SettingsManager.
   * 
   * @param rssOwlGui The Main Controller.
   */
  private SettingsManager(GUI rssOwlGui) {
    this.rssOwlGui = rssOwlGui;
    setName("Settings Manager Thread");
    setDaemon(true);
  }

  /**
   * Get the single instance of the SettingsManager.
   * 
   * @return The single instance of the SettingsManager.
   */
  public static SettingsManager getInstance() {
    if (instance == null)
      instance = new SettingsManager(GUI.rssOwlGui);
    return instance;
  }

  /**
   * Request save of Settings. Next time the Manager checks for the
   * <code>isSaveRequested</code> flag, Settings will be saved.
   */
  public void requestSave() {
    isSaveRequested = true;
  }

  /**
   * @see java.lang.Runnable#run()
   */
  public void run() {

    /** Run until stopped */
    while (!isStopped() && GUI.isAlive() && !isInterrupted()) {

      /** Sleep for some time */
      try {
        sleep(SLEEP_INTERVAL);
      } catch (InterruptedException e) {
        break;
      }

      /** Save Settings in a Exception safe manner */
      if (isSaveRequested && !isStopped() && GUI.isAlive() && !isInterrupted()) {
        try {
          internalSaveSettings();
        } catch (Exception e) {
          GUI.logger.log("SettingsManager#run()", e);
        } finally {
          isSaveRequested = false;
        }
      }

      /** Save Archive in a Exception safe manner */
      if (!isStopped() && GUI.isAlive() && !isInterrupted()) {
        try {
          rssOwlGui.getArchiveManager().flush();
        } catch (Exception e) {
          GUI.logger.log("SettingsManager#run()", e);
        }
      }
    }
  }

  private void internalSaveSettings() {
    GUI.display.asyncExec(new Runnable() {
      public void run() {

        /** Settings Files and Backup */
        File settings = new File(GlobalSettings.RSSOWL_SETTINGS_FILE);
        File backup = new File(GlobalSettings.RSSOWL_SETTINGS_BACKUP_FILE);

        /** Save Settings */
        new SettingsSaver(rssOwlGui).saveUserSettings(false);

        /** Backup the settings file */
        try {
          SimpleFileShop.copy(settings, backup);
        } catch (IOException e) {
          GUI.logger.log("SettingsManager#run()", e);
        }
      }
    });
  }

  /**
   * @see net.sourceforge.rssowl.controller.thread.ExtendedThread#stopThread()
   */
  public synchronized void stopThread() {
    super.stopThread();
    interrupt();
  }
}