/* nsIDOMSVGTransform replaceItem (in nsIDOMSVGTransform newItem, in unsigned long index); */
NS_IMETHODIMP nsSVGTransformList::ReplaceItem(nsIDOMSVGTransform *newItem,
                                              PRUint32 index,
                                              nsIDOMSVGTransform **_retval)
{
  NS_ENSURE_NATIVE_TRANSFORM(newItem, _retval);

  nsSVGValueAutoNotifier autonotifier(this);

  if (index >= PRUint32(mTransforms.Count()))
    return NS_ERROR_DOM_INDEX_SIZE_ERR;

  nsIDOMSVGTransform* oldItem = ElementAt(index);

  if (!mTransforms.ReplaceElementAt((void*)newItem, index)) {
    NS_NOTREACHED("removal of element failed");
    return NS_ERROR_UNEXPECTED;
  }

  nsCOMPtr<nsISVGValue> val = do_QueryInterface(oldItem);
  val->RemoveObserver(this);
  NS_RELEASE(oldItem);
  val = do_QueryInterface(newItem);
  val->AddObserver(this);
  NS_ADDREF(newItem);

  *_retval = newItem;
  NS_ADDREF(*_retval);
  return NS_OK;
}
/* nsIDOMSVGTransform replaceItem (in nsIDOMSVGTransform newItem, in unsigned long index); */
NS_IMETHODIMP nsSVGTransformList::ReplaceItem(nsIDOMSVGTransform *newItem,
                                              PRUint32 index,
                                              nsIDOMSVGTransform **_retval)
{
  NS_ENSURE_NATIVE_TRANSFORM(newItem, _retval);

  if (index >= mTransforms.Length())
    return NS_ERROR_DOM_INDEX_SIZE_ERR;

  nsSVGValueAutoNotifier autonotifier(this);

  nsIDOMSVGTransform* oldItem = ElementAt(index);

  mTransforms.ElementAt(index) = newItem;

  nsCOMPtr<nsISVGValue> val = do_QueryInterface(oldItem);
  val->RemoveObserver(this);
  NS_RELEASE(oldItem);
  val = do_QueryInterface(newItem);
  val->AddObserver(this);
  NS_ADDREF(newItem);

  *_retval = newItem;
  NS_ADDREF(*_retval);
  return NS_OK;
}
/* nsIDOMSVGTransform appendItem (in nsIDOMSVGTransform newItem); */
NS_IMETHODIMP nsSVGTransformList::AppendItem(nsIDOMSVGTransform *newItem,
                                             nsIDOMSVGTransform **_retval)
{
  NS_ENSURE_NATIVE_TRANSFORM(newItem, _retval);

  nsSVGValueAutoNotifier autonotifier(this);

  if (!AppendElement(newItem)) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

  *_retval = newItem;
  NS_ADDREF(*_retval);
  return NS_OK;
}
/* nsIDOMSVGTransform removeItem (in unsigned long index); */
NS_IMETHODIMP nsSVGTransformList::RemoveItem(PRUint32 index, nsIDOMSVGTransform **_retval)
{
  if (index >= mTransforms.Length()) {
    *_retval = nsnull;
    return NS_ERROR_DOM_INDEX_SIZE_ERR;
  }

  nsSVGValueAutoNotifier autonotifier(this);

  *_retval = ElementAt(index);

  mTransforms.RemoveElementAt(index);

  nsCOMPtr<nsISVGValue> val = do_QueryInterface(*_retval);
  val->RemoveObserver(this);

  // don't NS_ADDREF(*_retval)
  return NS_OK;
}
/* nsIDOMSVGTransform insertItemBefore (in nsIDOMSVGTransform newItem, in unsigned long index); */
NS_IMETHODIMP nsSVGTransformList::InsertItemBefore(nsIDOMSVGTransform *newItem,
                                                   PRUint32 index,
                                                   nsIDOMSVGTransform **_retval)
{
  NS_ENSURE_NATIVE_TRANSFORM(newItem, _retval);

  nsSVGValueAutoNotifier autonotifier(this);

  PRUint32 count = mTransforms.Count();

  if (!mTransforms.InsertElementAt((void*)newItem, (index < count)? index: count)) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

  NS_ADDREF(newItem);
  nsCOMPtr<nsISVGValue> val = do_QueryInterface(newItem);
  val->AddObserver(this);

  *_retval = newItem;
  NS_ADDREF(*_retval);
  return NS_OK;
}
/* nsIDOMSVGTransform removeItem (in unsigned long index); */
NS_IMETHODIMP nsSVGTransformList::RemoveItem(PRUint32 index, nsIDOMSVGTransform **_retval)
{
  nsSVGValueAutoNotifier autonotifier(this);

  if (index >= static_cast<PRUint32>(mTransforms.Count())) {
    *_retval = nsnull;
    return NS_ERROR_DOM_INDEX_SIZE_ERR;
  }

  *_retval = ElementAt(index);

  if (!mTransforms.RemoveElementAt(index)) {
    NS_NOTREACHED("removal of element failed");
    *_retval = nsnull;
    return NS_ERROR_UNEXPECTED;
  }

  nsCOMPtr<nsISVGValue> val = do_QueryInterface(*_retval);
  val->RemoveObserver(this);

  // don't NS_ADDREF(*_retval)
  return NS_OK;
}