/*   **********************************************************************  **
 **   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.controller.MessageBoxFactory;
import net.sourceforge.rssowl.util.GlobalSettings;
import net.sourceforge.rssowl.util.shop.FileShop;
import net.sourceforge.rssowl.util.shop.URLShop;

import org.eclipse.swt.SWT;

import java.io.IOException;
import java.net.URL;

/**
 * The Update Manager checks the version-file on a server for new releases of
 * RSSOwl and displays a message in a new tab if a new version is available. The
 * message also contains a list of new features if available. The Manager is a
 * thread to avoid freezing of RSSOwl while the update informations are re-
 * trieved.
 * 
 * @author <a href="mailto:bpasero@rssowl.org">Benjamin Pasero </a>
 * @version 1.2.3
 */
public class UpdateManager extends Thread {

  /**
   * Set the current major version of RSSOwl <br />
   * [Format: x.x]
   */
  public static final String MAJOR_VERSION = "1.2.3";

  /**
   * Set the current minor version of RSSOwl <br />
   * [Format: YYYY-MM-DD] <br />
   * [PR Format: Preview Release YYYY-MM-DD]
   */
  public static final String MINOR_VERSION = "2006-11-26";

  /** Changelog of newest version */
  private String changelog;

  /** True if the user wants to be informed even if no updated is available */
  private boolean displayNoNewVersionInfo;

  /** RSSOwl Version as String */
  private String onlineVersion;

  /** RSSOwl Maincontroller */
  private GUI rssOwlGui;

  /** If TRUE show an warning message when the connection fails */
  private boolean showErrorMessage;

  /**
   * Instantiate a new UpdateManager
   * 
   * @param rssOwlGui The RSSOwl Maincontroller
   */
  public UpdateManager(GUI rssOwlGui) {
    this(rssOwlGui, true);
  }

  /**
   * Instantiate a new UpdateManager
   * 
   * @param rssOwlGui The RSSOwl Maincontroller
   * @param showErrorMessage TRUE: Show warning message if con. fails
   */
  public UpdateManager(GUI rssOwlGui, boolean showErrorMessage) {
    this.rssOwlGui = rssOwlGui;
    this.showErrorMessage = showErrorMessage;
    displayNoNewVersionInfo = false;
    changelog = "";
    onlineVersion = getPublicVersion();
    setName("Update Manager Thread");
    setDaemon(true);
  }

  /**
   * Get the correct formatted public version identifier
   * 
   * @return String The public version
   */
  public static String getPublicVersion() {
    return MAJOR_VERSION + " " + MINOR_VERSION;
  }

  /** Load versionnumber and changelog from server */
  public void run() {
    try {

      /** Determine online version */
      getVersion();

      /**
       * If onlineversion differs from current version and the content of the
       * online version request was not overwritten by a proxy server that
       * forwarded the request to a different server. <br />
       * Versionnumber Format is for example: 1.0 2004-12-12 <br />
       */
      if (!GlobalSettings._IS_PRE_RELEASE && onlineVersion.indexOf(getPublicVersion()) < 0 && onlineVersion.length() < 20) {
        getChangelog();

        /** Only perform this Runnable if RSSOwl was not closed */
        if (GUI.isAlive()) {
          GUI.display.asyncExec(new Runnable() {
            public void run() {
              createInfoTab();
            }
          });
        }
      }

      /** Current version is up to date but the user wants to be informed */
      else if (displayNoNewVersionInfo && GUI.isAlive()) {

        /** Display a new tab with the info */
        GUI.display.asyncExec(new Runnable() {
          public void run() {
            createNoNewVersionInfo();
          }
        });
      }
    }

    /** Show Error if set so */
    catch (IOException e) {

      /** Give out warning if connection failed and display still opened */
      if (showErrorMessage && GUI.isAlive()) {
        GUI.display.asyncExec(new Runnable() {
          public void run() {
            createErrorConnectInfo();
          }
        });
      }
    }
  }

  /**
   * Set TRUE if the user wants to be informed even if no upted is available
   * 
   * @param displayNoNewVersionInfo Set to TRUE if RSSOwl should give out
   * information, even if no new version is available.
   */
  public void setDisplayNoNewVersionInfo(boolean displayNoNewVersionInfo) {
    this.displayNoNewVersionInfo = displayNoNewVersionInfo;
  }

  /**
   * Get changelog from server
   * 
   * @throws IOException If an IO Error occurs
   */
  private void getChangelog() throws IOException {
    changelog = FileShop.getContent(new URL(URLShop.RSSOWL_CHANGELOG_URL));
  }

  /**
   * Get version number from server
   * 
   * @throws IOException If an IO Error occurs
   */
  private void getVersion() throws IOException {
    onlineVersion = FileShop.getContent(new URL(URLShop.RSSOWL_UPDATE_URL));
  }

  /** Display warning message in a dialog */
  void createErrorConnectInfo() {
    MessageBoxFactory.showError(GUI.shell, GUI.i18n.getTranslation("MESSAGEBOX_MESSAGE_CON_ERROR"));
  }

  /** Display the message in the tab */
  void createInfoTab() {
    String title = GUI.i18n.getTranslation("DIALOG_TITLE_UPDATE") + ": RSSOwl " + onlineVersion.trim();

    /** Show the updatepanel tab */
    rssOwlGui.getRSSOwlNewsTabFolder().showUpdateAvailableTab(title, changelog);
  }

  /** Display the message in a dialog */
  void createNoNewVersionInfo() {
    MessageBoxFactory.showMessage(GUI.shell, SWT.ICON_INFORMATION, GUI.i18n.getTranslation("MENU_UPDATE"), GUI.i18n.getTranslation("MESSAGEBOX_MESSAGE_UPDATE"));
  }
}