package csc241.samples.stringList;

/** stringLinkedListItr class maintains "current position" on a List **/

public class stringLinkedListItr {
  /** The List. */
  protected stringLinkedList myList_;
  /** Current position. */
  protected ListNode current_;

  /**
   * Construct the list.
   * As a result of the construction, the current_ position is
   * the first item, unless the list is empty, in which case
   * the current_ is null.
   * @param anyList a LinkedList object to which this iterator is
   *     permanently bound.
   */
  public stringLinkedListItr( stringLinkedList anyList )  {
    myList_ = anyList;
    current_ = myList_.header_;
  }
  
  /**
   * Insert after the current position.
   * current is set to the inserted node on success.
   * @param x the item to insert.
   * @exception Exception if the current position is null.
   */
  public void insert( String x ) throws Exception  {
    if( current_ == null )
      throw new Exception( "Insertion error; invalid current" );
    
    ListNode newNode = new ListNode( x, current_.next_ );
    current_.next_ = newNode;
    current_ =  newNode;
  }
  
  /**
   * Insert at the beginning of the list.
   * current is set to the inserted node.
   * @param x the item to insert.
   */
  public void insertAtBeginning( String x )  {
    myList_.header_= new ListNode( x, myList_.header_ );
    current_ =  myList_.header_;
  }
  
  /**
   * Set the current position to the first node containing an item.
   * current is unchanged if x is not found.
   * @param x the item to search for.
   * @return true if the item is found, false otherwise.
   */
  public boolean find( String x )  {
    ListNode itr = myList_.header_;

    while( itr != null) {
      if(itr.element_.equals( x ) ) {
        current_ = itr;
        return true;
      }
      itr = itr.next_;
    }
    return false;
  }

  /**
   * Remove the first occurrence of an item.
   * current is set to the node at the beginning of the list on success;
   * remains unchanged otherwise.
   * @param x the item to remove.
   * @exception Exception if the item is not found.
   */
  public void remove( String x ) throws Exception  {
    if( myList_.header_ == null )
      throw new Exception( "Remove fails; empty list" );

    if (myList_.header_.element_.equals(x)) {
      myList_.header_ = myList_.header_.next_;
      current_ = myList_.header_;
      return;
    }
    ListNode itr = myList_.header_;
    
    while( itr.next_ != null) {
      if (itr.next_.element_.equals( x ) ) {
         itr.next_ = itr.next_.next_;
         current_ = myList_.header_;
         return;
      }
      itr = itr.next_;
    }
    throw new Exception( "Remove fails; element not in list" );
  }
  /**
   * Test if the current position references a valid list item.
   * @return true if the current position is not null
   */
  public boolean validCurrent( )  {
    return current_ != null;
  }

  /**
   * Return the item stored in the current_ position.
   * @return the stored item or null if the current_ position
   * is not in the list.
   */
  public String retrieve( )  {
    return validCurrent( ) ? current_.element_ : null;
  }

  /**
   * Set the current_ position to the first node in the list.
   * This operation is valid for empty lists.
   */
  public void first( )  {
    current_ = myList_.header_;
  }

  /**
   * Advance the current_ position to the next node in the list.
   * If the current_ position is null, then do nothing.
   * No exceptions are thrown by this routine because in the
   * most common use (inside a for loop), this would require the
   * programmer to add an unnecessary try/catch block.
   */
  public void advance( )  {
    if( current_ != null )
      current_ = current_.next_;
  }

  /**
   * return a string representing the list content
   **/
  public String dump () {
    String text;
    if (myList_.header_ == null) 
      text = new String ("List is Empty");
    else {
      text= new String("head-> ");
      ListNode temp;
      int last;
      for (temp=myList_.header_;temp != null;temp=temp.next_)
          text=text.concat(temp.element_ + "-> ");
    }
    return text;

  }
}

