/* Copyright (C) 1999-2003 by Peter Eastman

   This program is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
   Foundation; either version 2 of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
   PARTICULAR PURPOSE.  See the GNU General Public License for more details. */

package artofillusion.datahandling;

import java.lang.reflect.*;
import java.util.*;

// TODO(MB) Implementation should base on AbstractCOPYListOperation

/** Operation on array or List for deleting elements which are marked true
 *  in a boolean array.
 *
 * @author  Michael Butscher
 */
public class DeleteMarkedItemsListOp extends AbstractInplaceListOperation
{
  boolean[] markedItems;
  
  /** Constructor. This operation deletes all List items with a position index i
    in the list for that markedItems[i] is true.
   */
  public DeleteMarkedItemsListOp(boolean[] markedItems)
  {
    this.markedItems = markedItems;
  }
  
  /** Changes data as described.
    
    throws ArrayIndexOutOfBoundsException If data.size() != markedItems.length
  */
  public void applyInplace(List data)
  {
    if (data.size() != markedItems.length)
      throw new ArrayIndexOutOfBoundsException("Length mismatch");
    
    ListIterator iter = data.listIterator();

    for(int i = 0; i < markedItems.length; ++i)
    {
      iter.next();
      if (markedItems[i])
        iter.remove();
    }
  }
  
  /** Returns an int array which maps new index i (after deletion) to
    old index result[i].
   */
  public int[] getMappingNewToOld()
  {
    int newlen = 0;
    int i;
    
    for (i = 0; i < markedItems.length; i++)
      if (!markedItems[i])
	newlen++;
    
    int counter = 0;
    int[] result = new int[newlen];
    for(i = 0; i < markedItems.length; i++)
      if (!markedItems[i])
      {
        result[counter] = i;
        ++counter;
      }
       
    return result;
  }

  /** Returns an int array which maps old index i (before deletion) to
    new index result[i]. If old index i was deleted, result[i] == -1.
   */
  public int[] getMappingOldToNew()
  {
    int i;
    
    int counter = 0;
    int[] result = new int[markedItems.length];
    
    for (i = 0; i < markedItems.length; i++)
      if (!markedItems[i])
      {
        result[i] = counter;
        ++counter;
      }
      else
        result[i] = -1;
 
    return result;
  }
  
}
