/*   **********************************************************************  **
 **   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.dao;

import net.sourceforge.rssowl.controller.GUI;
import net.sourceforge.rssowl.controller.Quickview;
import net.sourceforge.rssowl.controller.dialog.ToolBarDialog;
import net.sourceforge.rssowl.controller.thread.AmphetaRateThread;
import net.sourceforge.rssowl.model.Category;
import net.sourceforge.rssowl.model.Favorite;
import net.sourceforge.rssowl.util.CryptoManager;
import net.sourceforge.rssowl.util.DateParser;
import net.sourceforge.rssowl.util.GlobalSettings;
import net.sourceforge.rssowl.util.i18n.Dictionary;
import net.sourceforge.rssowl.util.shop.FontShop;
import net.sourceforge.rssowl.util.shop.HotkeyShop;
import net.sourceforge.rssowl.util.shop.ProxyShop;
import net.sourceforge.rssowl.util.shop.StringShop;
import net.sourceforge.rssowl.util.shop.WidgetShop;
import net.sourceforge.rssowl.util.shop.XMLShop;

import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.jdom.Comment;
import org.jdom.Document;
import org.jdom.Element;

import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

/**
 * The SettingsSaver class is responsible to save all settings and favorites
 * into the user.xml settings file.
 * 
 * @author <a href="mailto:bpasero@rssowl.org">Benjamin Pasero </a>
 * @version 1.2.3
 */
public class SettingsSaver {
  private Document document;
  private Element root;
  private GUI rssOwlGui;

  /**
   * Instantiate a new SettingsSaver
   * 
   * @param rssOwlGui The Main Controller
   */
  public SettingsSaver(GUI rssOwlGui) {
    this.rssOwlGui = rssOwlGui;
    root = new Element("rssowl");
    document = new Document(root);
  }

  /**
   * Save all Settings. This Method has to be synchronized, because it might be
   * called from the SettingsManager Thread as well as from the Main Thread.
   * 
   * @param fromShutDownHook If TRUE, this Method is called from the Shutdown
   * Hook.
   */
  public synchronized void saveUserSettings(boolean fromShutDownHook) {

    /** Add Comment */
    if (!fromShutDownHook) {
      Comment comment = new Comment(" XML generated by RSSOwl (http://www.rssowl.org) on " + DateParser.formatDate(new Date(), true) + " ");
      document.getContent().add(0, comment);
    }

    /** Save Favorites / Categories / Blogrolls */
    Element favorites = new Element("favorites");
    root.addContent(favorites);

    Hashtable subCategorys = Category.getRootCategory().getSubCategories();
    saveFavoritesOrCategorys(subCategorys, favorites);

    /** Save Sash Weights */
    if (!fromShutDownHook)
      saveSashWeights();

    /** Save Shell Bounds */
    saveShellBounds();

    /** Save Proxysettings */
    saveProxySettings();

    /** Save Sort Order */
    saveSortOrder(GlobalSettings.sortOrder);

    /** Save ToolBar Items */
    if (!GlobalSettings.toolBarItems.equals(ToolBarDialog.getDefaultToolBarItems()))
      saveValue("toolBarItems", "value", GlobalSettings.toolBarItems);

    /** Save useSmallIcons */
    if (!GlobalSettings.useSmallIcons)
      saveBoolean("useSmallIcons", GlobalSettings.useSmallIcons);

    /** Save ToolBar Mode */
    if (GlobalSettings.toolBarMode != Quickview.TOOLBAR_MODE_ICONS_TEXT)
      saveValue("toolBarMode", "value", String.valueOf(GlobalSettings.toolBarMode));

    /** Save Confirmations */
    if (!GlobalSettings.confirmFavoriteDeletion)
      saveBoolean("confirmFavoriteDeletion", GlobalSettings.confirmFavoriteDeletion);

    if (!GlobalSettings.confirmCategoryDeletion)
      saveBoolean("confirmCategoryDeletion", GlobalSettings.confirmCategoryDeletion);

    if (!GlobalSettings.confirmBlogrollDeletion)
      saveBoolean("confirmBlogrollDeletion", GlobalSettings.confirmBlogrollDeletion);

    /** Save maxConnectionCount */
    if (GlobalSettings.maxConnectionCount != 32)
      saveValue("maxConnectionCount", "value", String.valueOf(GlobalSettings.maxConnectionCount));

    /** Save connectionTimeout */
    if (GlobalSettings.connectionTimeout != 30)
      saveValue("connectionTimeout", "value", String.valueOf(GlobalSettings.connectionTimeout));

    /** Save isQuickviewShown */
    if (!GlobalSettings.isQuickviewShown)
      saveBoolean("isQuickviewShown", GlobalSettings.isQuickviewShown);

    /** Save isToolBarShown */
    if (!GlobalSettings.isToolBarShown)
      saveBoolean("isToolBarShown", GlobalSettings.isToolBarShown);

    /** Save isTreeToolBarShown */
    if (!GlobalSettings.isTreeToolBarShown)
      saveBoolean("isTreeToolBarShown", GlobalSettings.isTreeToolBarShown);

    /** Save isFavoritesTreeShown */
    if (!GlobalSettings.isFavoritesTreeShown)
      saveBoolean("isFavoritesTreeShown", GlobalSettings.isFavoritesTreeShown);

    /** Save isWelcomeShown */
    if (!GlobalSettings.isWelcomeShown)
      saveBoolean("isWelcomeShown", GlobalSettings.isWelcomeShown);

    /** Save linkTreeWithTab */
    if (GlobalSettings.linkTreeWithTab)
      saveBoolean("linkTreeWithTab", GlobalSettings.linkTreeWithTab);

    /** Save showErrors */
    if (!GlobalSettings.showErrors)
      saveBoolean("showErrors", GlobalSettings.showErrors);

    /** Save autoSortNews */
    if (!GlobalSettings.autoSortNews)
      saveBoolean("autoSortNews", GlobalSettings.autoSortNews);

    /** Save autoCloseNewsPopup */
    if (!GlobalSettings.autoCloseNewsPopup)
      saveBoolean("autoCloseNewsPopup", GlobalSettings.autoCloseNewsPopup);

    /** Save animateNewsPopup */
    if (!GlobalSettings.animateNewsPopup)
      saveBoolean("animateNewsPopup", GlobalSettings.animateNewsPopup);

    /** Save tabPositionIsTop */
    if (!GlobalSettings.tabPositionIsTop)
      saveBoolean("tabPositionIsTop", GlobalSettings.tabPositionIsTop);

    /** Save showTabCloseButton */
    if (!GlobalSettings.showTabCloseButton)
      saveBoolean("showTabCloseButton", GlobalSettings.showTabCloseButton);

    /** Save blockPopups - Setting ignored on Linux */
    if (!GlobalSettings.blockPopups && !GlobalSettings.isLinux())
      saveBoolean("blockPopups", GlobalSettings.blockPopups);

    /** Save workOffline */
    if (GlobalSettings.workOffline)
      saveBoolean("workOffline", GlobalSettings.workOffline);

    /** Save reopenFeeds */
    if (GlobalSettings.reopenFeeds)
      saveBoolean("reopenFeeds", GlobalSettings.reopenFeeds);

    /** Save simpleTabs */
    if (!GlobalSettings.simpleTabs)
      saveBoolean("simpleTabs", GlobalSettings.simpleTabs);

    /** Save displaySingleTab */
    if (GlobalSettings.displaySingleTab)
      saveBoolean("displaySingleTab", GlobalSettings.displaySingleTab);

    /** Save localCacheFeeds */
    if (!GlobalSettings.localCacheFeeds)
      saveBoolean("localCacheFeeds", GlobalSettings.localCacheFeeds);

    /** Save isDoubleClickOpen */
    if (GlobalSettings.isDoubleClickOpen == GlobalSettings.useSingleClickOpen())
      saveBoolean("isDoubleClickOpen", GlobalSettings.isDoubleClickOpen);

    /** Save showTrayPopup */
    if (!GlobalSettings.showTrayPopup)
      saveBoolean("showTrayPopup", GlobalSettings.showTrayPopup);

    /** Save directOpen */
    if (GlobalSettings.directOpenNews)
      saveBoolean("isDirectOpenNews", GlobalSettings.directOpenNews);

    /** Save favDefaultOpenOnStartup */
    if (GlobalSettings.favDefaultOpenOnStartup)
      saveBoolean("favDefaultOpenOnStartup", GlobalSettings.favDefaultOpenOnStartup);

    /** Save favDefaultReloadOnStartup */
    if (GlobalSettings.favDefaultReloadOnStartup)
      saveBoolean("favDefaultReloadOnStartup", GlobalSettings.favDefaultReloadOnStartup);

    /** Save favDefaultAutoReloadInterval */
    if (GlobalSettings.favDefaultAutoReloadInterval != 60)
      saveValue("favDefaultAutoReloadInterval", "value", String.valueOf(GlobalSettings.favDefaultAutoReloadInterval));

    /** Save showSystrayIcon */
    if (GlobalSettings.showSystrayIcon)
      saveBoolean("showSystrayIcon", GlobalSettings.showSystrayIcon);

    /** Save setProxyForAllFavorites */
    if (!GlobalSettings.setProxyForAllFavorites)
      saveBoolean("setProxyForAllFavorites", GlobalSettings.setProxyForAllFavorites);

    /** Save markAllReadOnMinimize */
    if (GlobalSettings.markAllReadOnMinimize)
      saveBoolean("markAllReadOnMinimize", GlobalSettings.markAllReadOnMinimize);

    /** Save markFeedReadOnTabClose */
    if (GlobalSettings.markFeedReadOnTabClose)
      saveBoolean("markFeedReadOnTabClose", GlobalSettings.markFeedReadOnTabClose);

    /** Save showChannelInfo */
    if (!GlobalSettings.showChannelInfo)
      saveBoolean("showChannelInfo", GlobalSettings.showChannelInfo);

    /** Save directOpenEachNews */
    if (GlobalSettings.directOpenEachNews)
      saveBoolean("directOpenEachNews", GlobalSettings.directOpenEachNews);

    /** Save openNewBrowserWindow */
    if (!GlobalSettings.openNewBrowserWindow)
      saveBoolean("openNewBrowserWindow", GlobalSettings.openNewBrowserWindow);

    /** Save openBrowserExtern */
    saveBoolean("openBrowserExtern", GlobalSettings.openBrowserExtern);

    /** Save focusNewTabs */
    if (!GlobalSettings.focusNewTabs)
      saveBoolean("focusNewTabs", GlobalSettings.focusNewTabs);

    /** Save checkUpdate */
    if (!GlobalSettings.checkUpdate)
      saveBoolean("checkUpdate", GlobalSettings.checkUpdate);

    /** Save trayOnExit */
    if (GlobalSettings.trayOnExit)
      saveBoolean("trayOnExit", GlobalSettings.trayOnExit);

    /** Save trayOnStartup */
    if (GlobalSettings.trayOnStartup)
      saveBoolean("trayOnStartup", GlobalSettings.trayOnStartup);

    /** Save useBrowserForNewsText */
    if (GlobalSettings.useInternalBrowser())
      saveBoolean("useBrowserForNewsText", GlobalSettings.useBrowserForNewsText);

    /** Save htmlFormatMail */
    if (!GlobalSettings.htmlFormatMail)
      saveBoolean("htmlFormatMail", GlobalSettings.htmlFormatMail);

    /** Save isThreeColumnGUI */
    if (GlobalSettings.isThreeColumnGUI)
      saveBoolean("isThreeColumnGUI", GlobalSettings.isThreeColumnGUI);

    /** Save language */
    saveValue("language", "value", Dictionary.selectedLanguage);

    /** Save blogger */
    if (!GlobalSettings.bloggerPath.equals(""))
      saveValue("bloggerPath", "value", GlobalSettings.bloggerPath);

    if (!GlobalSettings.bloggerArguments.equals(""))
      saveValue("bloggerArguments", "value", GlobalSettings.bloggerArguments);

    /** Save Colors */
    if (!GlobalSettings.linkColor.equals(new RGB(0, 0, 255)))
      saveColor("linkColor", GlobalSettings.linkColor);

    if (!GlobalSettings.syntaxHighlightColor.equals(new RGB(255, 255, 0)))
      saveColor("syntaxHighlightColor", GlobalSettings.syntaxHighlightColor);

    /** Save Fonts */
    saveFont("textfont", FontShop.textFont);
    saveFont("treefont", FontShop.treeFont);
    saveFont("tablefont", FontShop.tableFont);
    saveFont("headerfont", FontShop.headerFont);
    saveFont("dialogfont", FontShop.dialogFont);

    /** Save Encoding */
    if (!GlobalSettings.charEncoding.equals("UTF-8"))
      saveValue("encoding", "name", GlobalSettings.charEncoding);

    /** Save path to custom browser */
    if (!GlobalSettings.customBrowser.equals(""))
      saveValue("customBrowser", "path", GlobalSettings.customBrowser);

    /** Save args of custom browser */
    if (!GlobalSettings.customBrowserArguments.equals(""))
      saveValue("customBrowserArguments", "value", GlobalSettings.customBrowserArguments);

    /*
     * if (!GlobalSettings.amphetaRateUserID.equals(""))
     * saveValue("amphetaRateUserId", "userId",
     * GlobalSettings.amphetaRateUserID); if
     * (!GlobalSettings.amphetaRateUsername.equals(""))
     * saveValue("amphetaRateUsername", "username",
     * GlobalSettings.amphetaRateUsername); if
     * (!GlobalSettings.amphetaRatePassword.equals(""))
     * saveValue("amphetaRatePassword", "password",
     * GlobalSettings.amphetaRatePassword); saveRatings();
     */

    /** Save the hotkeys */
    saveHotkeys();

    /** Save mailSubject */
    if (!GlobalSettings.mailSubject.equals("RSSOwl NewsTip: [TITLE]"))
      saveValue("mailSubject", GlobalSettings.mailSubject);

    /** Save mailBody */
    if (!GlobalSettings.mailBody.equals(GUI.i18n.getTranslation("LABEL_TITLE") + ": [TITLE]\nURL: [LINK]"))
      saveValue("mailBody", GlobalSettings.mailBody);

    /** Save favorites tree selection */
    saveValue("treeSelection", GlobalSettings.selectedTreeItem);

    /** Save displayed feeds if "reopenFeeds" is TRUE */
    if (GlobalSettings.reopenFeeds)
      saveReopenFeeds(GUI.rssOwlGui.getRSSOwlNewsTabFolder().getLastOpenedFeeds());

    /** Write the new DOM into user.xml File */
    XMLShop.writeXML(document, GlobalSettings.RSSOWL_SETTINGS_FILE);
  }

  /**
   * Save a Boolean value to the user.xml
   * 
   * @param name Name of the element
   * @param state TRUE or FALSE
   */
  private void saveBoolean(String name, boolean state) {
    Element element = new Element(name);
    root.addContent(element);
    element.setAttribute("value", String.valueOf(state));
  }

  /**
   * Save a color
   * 
   * @param elementName The name of the element
   * @param color The color to save
   */
  private void saveColor(String elementName, RGB color) {
    Element element = new Element(elementName);
    root.addContent(element);
    element.setAttribute("red", String.valueOf(color.red));
    element.setAttribute("green", String.valueOf(color.green));
    element.setAttribute("blue", String.valueOf(color.blue));
  }

  /**
   * Save the selected font
   * 
   * @param name Font name
   * @param font The font to save
   */
  private void saveFont(String name, Font font) {

    /** Only save if font is given */
    if (FontShop.isset(font)) {
      Element element = new Element(name);
      root.addContent(element);
      element.setAttribute("name", font.getFontData()[0].getName());
      element.setAttribute("height", String.valueOf(font.getFontData()[0].getHeight()));
      element.setAttribute("style", String.valueOf(font.getFontData()[0].getStyle()));
    }
  }

  /**
   * Save hotkeys
   */
  private void saveHotkeys() {
    Element hotkeys = new Element("hotkeys");
    root.addContent(hotkeys);

    /** For each hotkey */
    Enumeration keys = HotkeyShop.hotKeys.keys();
    while (keys.hasMoreElements()) {
      String type = (String) keys.nextElement();
      Element typeElement = new Element(type);
      typeElement.setAttribute("keyName", HotkeyShop.getHotkeyName(type));
      typeElement.setAttribute("keyInt", String.valueOf(HotkeyShop.getHotkeyValue(type)));
      hotkeys.addContent(typeElement);
    }
  }

  /**
   * Save Proxysettings
   */
  private void saveProxySettings() {
    Element proxy = new Element("proxy");
    root.addContent(proxy);
    CryptoManager rssOwlCryptoManager = CryptoManager.getInstance();
    Enumeration settings = ProxyShop.proxySettings.keys();

    /** Foreach proxy setting */
    while (settings.hasMoreElements()) {
      String key = (String) settings.nextElement();

      /** Special treat username */
      if (key.equals("username")) {
        String username = (String) ProxyShop.proxySettings.get(key);
        if (StringShop.isset(username))
          rssOwlCryptoManager.addItem(CryptoManager.PROXY_USER_KEY, username);
        else
          rssOwlCryptoManager.removeItem(CryptoManager.PROXY_USER_KEY);
      }

      /** Special treat password */
      else if (key.equals("password")) {
        String password = (String) ProxyShop.proxySettings.get(key);
        if (StringShop.isset(password))
          rssOwlCryptoManager.addItem(CryptoManager.PROXY_PASSWORD_KEY, password);
        else
          rssOwlCryptoManager.removeItem(CryptoManager.PROXY_PASSWORD_KEY);
      }

      /** Special treat domain */
      else if (key.equals("domain")) {
        String domain = (String) ProxyShop.proxySettings.get(key);
        if (StringShop.isset(domain))
          rssOwlCryptoManager.addItem(CryptoManager.PROXY_DOMAIN_KEY, domain);
        else
          rssOwlCryptoManager.removeItem(CryptoManager.PROXY_DOMAIN_KEY);
      }

      /** Normal element, add to XML */
      else {
        Element settingElement = new Element(key);
        settingElement.setText((String) ProxyShop.proxySettings.get(key));
        proxy.addContent(settingElement);
      }
    }
  }

  /**
   * Save all ratings that have not yet been submitted
   */
  private void saveRatings() {
    Hashtable ratings = AmphetaRateThread.getRatings();
    Enumeration keys = ratings.keys();

    /** Foreach rating */
    while (keys.hasMoreElements()) {
      String key = (String) keys.nextElement();
      Element rating = new Element("rating");
      rating.setAttribute("key", key);
      rating.setText((String) ratings.get(key));
      root.addContent(rating);
    }
  }

  /**
   * Save the feeds that RSSOwl shall reopen after application start.
   * 
   * @param feeds Vector with URLs of the feeds
   */
  private void saveReopenFeeds(Vector feeds) {
    Element element = new Element("reopenFeedsList");

    /** Foreach feed */
    for (int a = 0; a < feeds.size(); a++) {
      Element feed = new Element("feed");
      feed.setAttribute("url", (String) feeds.get(a));
      element.addContent(feed);
    }
    root.addContent(element);
  }

  /**
   * Save weights of the SashForms
   */
  private void saveSashWeights() {

    /** Content Sash */
    if (WidgetShop.isset(rssOwlGui.getContentSash())) {
      Element sashWeight = new Element("sashweight");
      sashWeight.setAttribute("name", "holdContentSash");
      int[] weights = rssOwlGui.getContentSash().getWeights();
      String weightString = String.valueOf(weights[0]);

      /** Foreach weight */
      for (int a = 1; a < weights.length; a++)
        weightString += ',' + String.valueOf(weights[a]);

      sashWeight.setAttribute("weight", weightString);
      root.addContent(sashWeight);
    }

    /** News Sash */
    if (WidgetShop.isset(rssOwlGui.getNewsSash())) {
      Element sashWeight = new Element("sashweight");
      sashWeight.setAttribute("name", "holdNewsSash");
      int[] weights = rssOwlGui.getNewsSash().getWeights();
      String weightString = String.valueOf(weights[0]);

      /** Foreach weight */
      for (int a = 1; a < weights.length; a++)
        weightString += ',' + String.valueOf(weights[a]);

      sashWeight.setAttribute("weight", weightString);
      root.addContent(sashWeight);
    }
  }

  /**
   * Save Shell Bounds
   */
  private void saveShellBounds() {
    Element shell = new Element("shell");
    root.addContent(shell);

    /** Maximized State - Not for Mac */
    if (!GlobalSettings.isMac())
      shell.setAttribute("maximized", String.valueOf(GlobalSettings.isShellMaximized).toLowerCase());

    /** Bounds */
    if (GlobalSettings.shellBounds != null) {
      Rectangle bounds = GlobalSettings.shellBounds;
      shell.setAttribute("height", String.valueOf(bounds.height));
      shell.setAttribute("width", String.valueOf(bounds.width));
      shell.setAttribute("x", String.valueOf(bounds.x));
      shell.setAttribute("y", String.valueOf(bounds.y));
    }
  }

  /**
   * Save the sort Order to apply to News
   * 
   * @param sortOrderVector The sort order
   */
  private void saveSortOrder(ArrayList sortOrderVector) {
    Element sortOrder = new Element("sortOrder");
    for (int a = 0; a < sortOrderVector.size(); a++) {
      Element sortItem = new Element((String) sortOrderVector.get(a));
      sortItem.setAttribute("level", String.valueOf(a));
      sortOrder.addContent(sortItem);
    }
    root.addContent(sortOrder);
  }

  /**
   * Save a setting to the settings XML file
   * 
   * @param elementName Name of the element
   * @param value Value of the element
   */
  private void saveValue(String elementName, String value) {
    saveValue(elementName, null, value);
  }

  /**
   * Save a setting to the settings XML file
   * 
   * @param elementName Name of the element
   * @param attribute Attribute name of the element
   * @param value Attribute value of the element
   */
  private void saveValue(String elementName, String attribute, String value) {
    if (value == null)
      value = "";

    Element element = new Element(elementName);
    root.addContent(element);

    if (attribute != null)
      element.setAttribute(attribute, value);
    else
      element.setText(value);
  }

  /**
   * Save Categorys and Favorits to the XML. This method is called recursivly to
   * support nesting of categorys. Blogroll are saved via URL / Path to the XML
   * of the blogroll.
   * 
   * @param categorys Current working Categorys
   * @param element Current working Element
   */
  void saveFavoritesOrCategorys(Hashtable categorys, Element element) {
    Enumeration elements = categorys.elements();

    /** For each category */
    while (elements.hasMoreElements()) {
      Category rssOwlSubCategory = (Category) elements.nextElement();

      /** This category is not from a blogroll */
      if (!rssOwlSubCategory.isBlogroll()) {
        Element category = new Element("category");
        category.setAttribute("name", rssOwlSubCategory.getName());

        /** Save expanded state */
        if (rssOwlSubCategory.isExpanded())
          category.setAttribute("isExpanded", String.valueOf(rssOwlSubCategory.isExpanded()));

        /** Add to Element */
        element.addContent(category);

        /** Recursivly save nested categorys */
        saveFavoritesOrCategorys(rssOwlSubCategory.getSubCategories(), category);

        /** Save Favorites */
        Hashtable favorits = rssOwlSubCategory.getFavorites();
        Enumeration favElements = favorits.elements();
        while (favElements.hasMoreElements()) {
          Favorite rssOwlFavorite = (Favorite) favElements.nextElement();

          /** Create a new Element: Link */
          Element link = new Element("link");
          link.setText(rssOwlFavorite.getUrl());
          link.setAttribute("title", rssOwlFavorite.getTitle());

          /** Information about: Error Loading */
          if (rssOwlFavorite.isErrorLoading())
            link.setAttribute("errorLoading", String.valueOf(rssOwlFavorite.isErrorLoading()));

          /** Information about: Load on Startup */
          if (rssOwlFavorite.isLoadOnStartup())
            link.setAttribute("loadOnStartup", String.valueOf(rssOwlFavorite.isLoadOnStartup()));

          /** Information about: Open on Startup */
          if (rssOwlFavorite.isOpenOnStartup())
            link.setAttribute("openOnStartup", String.valueOf(rssOwlFavorite.isOpenOnStartup()));

          /** Information about: Use Proxy */
          if (rssOwlFavorite.isUseProxy())
            link.setAttribute("useproxy", String.valueOf(rssOwlFavorite.isUseProxy()));

          /** Information about: Update Interval */
          if (rssOwlFavorite.getUpdateInterval() != 0)
            link.setAttribute("updateInterval", String.valueOf(rssOwlFavorite.getUpdateInterval()));

          /** Meta Infos */
          if (rssOwlFavorite.getUnreadNewsCount() > 0)
            link.setAttribute("new", String.valueOf(rssOwlFavorite.getUnreadNewsCount()));

          if (StringShop.isset(rssOwlFavorite.getDescription()))
            link.setAttribute("description", rssOwlFavorite.getDescription());

          if (StringShop.isset(rssOwlFavorite.getLanguage()))
            link.setAttribute("language", rssOwlFavorite.getLanguage());

          if (StringShop.isset(rssOwlFavorite.getHomepage()))
            link.setAttribute("homepage", rssOwlFavorite.getHomepage());

          link.setAttribute("creationDate", (rssOwlFavorite.getCreationDate() != 0) ? String.valueOf(rssOwlFavorite.getCreationDate()) : String.valueOf(new Date().getTime()));
          link.setAttribute("lastVisitDate", String.valueOf(rssOwlFavorite.getLastVisitDate()));

          /** Add link to category */
          category.addContent(link);
        }
      }

      /** This category is from a blogroll. Only add the URL / Path */
      else {
        Element category = new Element("category");
        category.setAttribute("name", rssOwlSubCategory.getName());
        category.setAttribute("useproxy", String.valueOf(rssOwlSubCategory.isUseProxy()));
        category.setAttribute("url", rssOwlSubCategory.getPathToBlogroll());
        element.addContent(category);
      }
    }
  }
}