// ============================================================================
// File:               $File$
//
// Project:            
//
// Purpose:            
//
// Author:             Rammi
//
// Copyright Notice:   (c) 2005  Rammi (rammi@caff.de)
//                     This code is in the public domain.
//                     Use at own risk.
//                     No guarantees given.
//
// Latest change:      $Date$
//
// History:	       $Log$
//=============================================================================
package de.caff.util.settings.swing;

import de.caff.util.settings.UrlListPreferenceProperty;

import java.util.*;
import java.util.prefs.Preferences;

/**
 *  Editable URL list preference property.
 *
 *  @author <a href="mailto:rammi@caff.de">Rammi</a>
 *  @version $Revision$
 */
public class SwingUrlListPreferenceProperty
        extends AbstractBasicSimpleEditablePreferenceProperty
        implements UrlListPreferenceProperty
{
  /** The preference key suffix for the number of entries. */
  private static final String PREF_KEY_SUFFIX_NR = "NR";

  /** The list of URLs. Elements are Strings. */
  private List urlList;

  /**
   *  Create a URL list with the given basic name and basic tag.
   *  @param basicName basic name
   *  @param baseTag   basic I18n tag
   *  @param defaultList start list
   */
  public SwingUrlListPreferenceProperty(String basicName, String baseTag, Collection defaultList)
  {
    super(basicName, baseTag);
    if (defaultList != null) {
      urlList = new ArrayList(defaultList);
    }
    else {
      urlList = new ArrayList();
    }
  }

  /**
   * Get the editor components for editing this preference property.
   *
   * @param l locale used for i18n
   * @return editor component
   */
  public EditorProvider getEditorProvider(Locale l)
  {
    return new UrlListEditor(this, l);
  }

  /**
   * Read the property value from the preferences.
   *
   * @param preferences preferences from where to read the property value
   */
  public void readFrom(Preferences preferences)
  {
    final String tagPrefix = getBasicName();
    int size = preferences.getInt(tagPrefix+PREF_KEY_SUFFIX_NR, -1);
    if (size == -1) {
      // previously unset, keep swing
    }
    else {
      List oldList = new ArrayList(urlList);
      urlList = new ArrayList(size);
      for (int index = 0;  index < size;  ++index) {
        String url = preferences.get(tagPrefix+index, null);
        if (url != null) {
          urlList.add(url);
        }
      }
      boolean changed;
      if (oldList.size() != urlList.size()) {
        changed = true;
      }
      else {
        Iterator itOld = oldList.iterator();
        Iterator itNew = urlList.iterator();
        changed = false;
        while (itOld.hasNext()  &&  itNew.hasNext()) {
          if (!itOld.next().equals(itNew.next())) {
            changed = true;
            break;
          }
        }
        changed = changed  ||  (itOld.hasNext() ^ itNew.hasNext());
      }
      if (changed) {
        fireValueChange(getBasicName(), oldList, urlList);
      }
    }
  }

  /**
   * Store the current property value in the preferences.
   *
   * @param preferences preferences where to store the property value
   */
  public void storeTo(Preferences preferences)
  {
    final String tagPrefix = getBasicName();
    if (urlList == null) {
      preferences.putInt(tagPrefix+PREF_KEY_SUFFIX_NR, 0);
    }
    else {
      preferences.putInt(tagPrefix+PREF_KEY_SUFFIX_NR, urlList.size());
      int index = 0;
      for (Iterator iterator = urlList.iterator(); iterator.hasNext();  ++index) {
        String url = (String)iterator.next();
        preferences.put(tagPrefix+index, url);
      }
    }
  }

  /**
   *  Add an URL to the end of the list.
   *  @param url string representing an URL
   */
  public void addUrl(String url)
  {
    addUrl(url, -1);
  }

  /**
   *  Insert an URL at the given position. If the position is invalid the
   *  URL is added to the end.
   *  @param url string representing an URL
   *  @param pos insertion position
   */
  public void addUrl(String url, int pos)
  {
    List oldList = new ArrayList(urlList);
    if (pos < 0  &&  pos >= urlList.size()) {
      urlList.add(url);
    }
    else {
      urlList.add(pos, url);
    }
    fireValueChange(getBasicName(), oldList, urlList);
  }

  /**
   *  Remove the URL at the given position.
   *  If the position is invalid nothing happens.
   *  @param pos position to remove from list
   */
  public void remove(int pos)
  {
    if (pos >= 0  &&  pos < urlList.size()) {
      List oldList = new ArrayList(urlList);
      urlList.remove(pos);
      fireValueChange(getBasicName(), oldList, urlList);
    }
  }

  /**
   *  Exchange two entries in the URL list.
   *  @param pos1 position of first entry
   *  @param pos2 position of second entry
   */
  public void swap(int pos1, int pos2)
  {
    if (pos1 >= 0  &&  pos1 < urlList.size()  &&
        pos2 >= 0  &&  pos2 < urlList.size()  &&
        pos1 != pos2) {
      List oldList = new ArrayList(urlList);
      Collections.swap(urlList, pos1, pos2);
      fireValueChange(getBasicName(), oldList, urlList);
    }
  }

  /**
   *  Get the collection of URLs.
   *  @return URL list
   */
  public Collection getUrlList()
  {
    return Collections.unmodifiableCollection(urlList);
  }

  /**
   *  Set the URL list.
   *  @param newList new URL list
   */
  void setUrlList(Collection newList)
  {
    boolean changed;
    if (newList.size() != urlList.size()) {
      changed = true;
    }
    else {
      Iterator itOld = urlList.iterator();
      Iterator itNew = newList.iterator();
      changed = false;
      while (itOld.hasNext()  &&  itNew.hasNext()) {
        if (!itOld.next().equals(itNew.next())) {
          changed = true;
          break;
        }
      }
      changed = changed  ||  (itOld.hasNext() ^ itNew.hasNext());
    }
    Collection oldList = urlList;
    urlList = new ArrayList(newList);
    if (changed) {
      fireValueChange(getBasicName(), oldList, urlList);
    }
  }
}
