/** Defines the Wales_PointOfInterest_Category class.
 *
 * @author Josh Zerin <josh.zerin@standingdog.com>
 * @since Wednesday, April 15, 2009
 *
 * @package HotelWales
 * @subpackage Library
 */

/** A category of points of interest on a GMap view.
 *
 * @package PointOfInterest
 */
function Wales_PointOfInterest_Category(  )
{
  /**#@+ @access private */
  var

    /** Unique identifier for this POI category.
     *
     * @var Number
     */
    $myUID = Wales_PointOfInterest_Controller.generateUID(),

    /** Link used to toggle pins for this category.
     *
     * @var jQuery
     */
    $myLink,

    /** The name of the category.
     *
     * @var String
     */
    $myName,

    /** The pin icon to use for points of interest that don't have a custom one.
     *
     * @var String Image URL
     */
    $myPinIcon,

    /** Points of interest attached to this category.
     *
     * @var Object
     */
    $myPointsOfInterest = {};
  /**#@-*/

  /** Accessor for $myUID.
   *
   * @return Number
   */
  this['getUID'] =
    function(  )
    {
      return $myUID;
    };

  /** Accessor for $myLink.  Note:  Might not be attached to the DOM yet.
   *
   * @return jQuery
   */
  this['getLink'] =
    function(  )
    {
      if( typeof($myLink) == 'undefined' )
      {
        /* Make this available to callbacks. */
        var $this = this;

        $myLink =
          $(document.createElement('a'))
            .attr('href', '#')
            .text(this.getName())
            .click( function(  ) {
              var $state = $MapController.togglePins($this);

              /* Make toggled links pretty. */
              for( $uid in $this.getPointsOfInterest() )
              {
                $this.getPointsOfInterest()[$uid].getLink()
                  .toggleClass('poi-selected', $state);
              }

              return false;
            });
      }

      return $myLink;
    };

  /** Accessor for $myName.
   *
   * @return String
   */
  this['getName'] =
    function(  )
    {
      return $myName;
    };

  /** Modifier for $myName.
   *
   * @param String $name
   *
   * @return Wales_PointOfInterest_Category this (for chaining).
   */
  this['setName'] =
    function( $name )
    {
      /* $name must be a String. */
      if( ! ($name && $name.constructor == String) )
      {
        $name = new String($name);
      }

      $myName = $name;
      return this;
    };

  /** Accessor for $myPinIcon.
   *
   * @return String Image URL
   */
  this['getPinIcon'] =
    function(  )
    {
      return $myPinIcon;
    };

  /** Modifier for $myPinIcon.
   *
   * @param String $icon Image URL
   *
   * @return Wales_PointOfInterest_Category this (for chaining).
   */
  this['setPinIcon'] =
    function( $icon )
    {
      /* $icon must be a String. */
      if( ! ($icon && $icon.constructor == String) )
      {
        $icon = new String($icon);
      }

      $myPinIcon = $icon;
      return this;
    };

  /** Accessor for $myPointsOfInterest.
   *
   * @return Object Returns a reference to $myPointsOfInterest.  Play nice!
   */
  this['getPointsOfInterest'] =
    function(  )
    {
      return $myPointsOfInterest;
    };

  /** Returns a specific POI from the category.
   *
   * @param Number|Wales_PointOfInterest $uid Can also be a POI instance
   *  (generally used to see if that point is attached to the category).
   *
   * @return Wales_PointOfInterest|Boolean Returns the POI if it is attached or
   *  false if it is not.
   */
  this['getPointOfInterest'] =
    function( $uid )
    {
      /* Validate $uid. */
      if( $uid )
      {
        if( $uid.constructor == Wales_PointOfInterest )
        {
          $uid = $uid.getUID();
        }
        else if( $uid.constructor != Number )
        {
          $uid = parseInt($uid);
        }

        if( ! isNaN($uid) )
        {
          if( typeof($myPointsOfInterest[$uid]) == 'undefined' )
          {
            return false;
          }
          else
          {
            return $myPointsOfInterest[$uid];
          }
        }
      }

      throw 'Invalid UID passed to getPointOfInterest().';
    };

  /** Attaches a point of interest to $myPointsOfInterest.
   *
   * @param Wales_PointOfInterest $PointOfInterest
   *
   * @return Wales_PointOfInterest_Category this (for chaining).
   */
  this['attach'] =
    function( $PointOfInterest )
    {
      /* Validate $PointOfInterest. */
      if( $PointOfInterest && $PointOfInterest.constructor == Wales_PointOfInterest )
      {
        $myPointsOfInterest[$PointOfInterest.getUID()] = $PointOfInterest;

        /* Fix reciprocal reference if necessary. */
        if( $PointOfInterest.getCategory() != this )
        {
          $PointOfInterest.setCategory(this);
        }
      }
      else
      {
        throw 'Can only attach Wales_PointOfInterest instances.';
      }

      return this;
    };
}