// ============================================================================
// 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;

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

/**
 *  A preference property which describes a bounds. 
 *  A bounds is consisting of a position and a dimension.
 *
 *  @author <a href="mailto:rammi@caff.de">Rammi</a>
 *  @version $Revision$
 */
public class BoundsPreferenceProperty
        extends AbstractBasicPreferenceProperty
{
  private static final String EXT_X      = "-X";
  private static final String EXT_Y      = "-Y";
  private static final String EXT_WIDTH  = "-WIDTH";
  private static final String EXT_HEIGHT = "-HEIGHT";

  private Rectangle bounds;

  public BoundsPreferenceProperty(String basicName)
  {
    super(basicName);
  }

  /**
   * Read the property value from the preferences.
   *
   * @param preferences preferences from where to read the property value
   */
  public void readFrom(Preferences preferences)
  {
    final String prefix = getBasicName();
    int w = preferences.getInt(prefix+EXT_WIDTH,  0);
    int h = preferences.getInt(prefix+EXT_HEIGHT, 0);

    if (w > 0  &&  h > 0) {
      int x = preferences.getInt(prefix+EXT_X,      0);
      int y = preferences.getInt(prefix+EXT_Y,      0);
      setBounds(new Rectangle(x, y, w, h));
    }
    else {
      setBounds((Rectangle)null);
    }
  }

  /**
   * Store the current property value in the preferences.
   *
   * @param preferences preferences where to store the property value
   */
  public void storeTo(Preferences preferences)
  {
    final String prefix = getBasicName();
    if (bounds == null) {
      preferences.remove(prefix+EXT_X);
      preferences.remove(prefix+EXT_Y);
      preferences.remove(prefix+EXT_WIDTH);
      preferences.remove(prefix+EXT_HEIGHT);
    }
    else {
      preferences.putInt(prefix+EXT_X,      bounds.x);
      preferences.putInt(prefix+EXT_Y,      bounds.y);
      preferences.putInt(prefix+EXT_WIDTH,  bounds.width);
      preferences.putInt(prefix+EXT_HEIGHT, bounds.height);
    }
  }

  /**
   *  Set the bounds of the given window.
   *  @param window window which bounds should be set
   *  @return <code>true</code> if the bounds of the window are set,
   *          otherwise <code>false</code>
   */
  public boolean setWindowBounds(Window window)
  {
    if (bounds != null) {
      window.setBounds(bounds.x, bounds.y, bounds.width, bounds.height);
      return true;
    }
    return false;
  }

  /**
   *  Get the bounds of the window and store them in the preferences.
   *  @param preferences preferences to store to
   *  @param window window which bounds are stored
   */
  public void storeWindowBounds(Preferences preferences, Window window)
  {
    bounds = window.getBounds();
    storeTo(preferences);
  }

  /**
   *  Set the bounds directly.
   *  @param bounds new bounds
   */
  public void setBounds(Rectangle bounds)
  {
    if (bounds == null) {
      if (this.bounds != null) {
        Rectangle oldBounds = this.bounds;
        this.bounds = null;
        fireValueChange(getBasicName(), oldBounds, bounds);
      }
    }
    else {
      if (!bounds.equals(this.bounds)) {
        Rectangle oldBounds = this.bounds;
        this.bounds = new Rectangle(bounds);
        fireValueChange(getBasicName(), oldBounds, bounds);
      }
    }
  }

  /**
   *  Set the bounds directly.
   *  @param window window from which to set the bounds
   */
  public void setBounds(Window window)
  {
    setBounds(window.getBounds());
  }

}
