/* void setSkewY (in float angle); */
NS_IMETHODIMP nsSVGTransform::SetSkewY(float angle)
{
  NS_ENSURE_FINITE(angle, NS_ERROR_ILLEGAL_VALUE);

  float ta = static_cast<float>(tan(angle * radPerDegree));

  NS_ENSURE_FINITE(ta, NS_ERROR_DOM_SVG_INVALID_VALUE_ERR);

  WillModify();
  
  mType = SVG_TRANSFORM_SKEWY;
  mAngle = angle;

  NS_REMOVE_SVGVALUE_OBSERVER(mMatrix);
  mMatrix->SetA(1.0f);
  mMatrix->SetB(ta);
  mMatrix->SetC(0.0f);
  mMatrix->SetD(1.0f);
  mMatrix->SetE(0.0f);
  mMatrix->SetF(0.0f);
  NS_ADD_SVGVALUE_OBSERVER(mMatrix);

  DidModify();
  return NS_OK;
}
/* void setRotate (in float angle, in float cx, in float cy); */
NS_IMETHODIMP nsSVGTransform::SetRotate(float angle, float cx, float cy)
{
  NS_ENSURE_FINITE3(angle, cx, cy, NS_ERROR_ILLEGAL_VALUE);

  WillModify();
  
  mType = SVG_TRANSFORM_ROTATE;
  mAngle = angle;
  mOriginX = cx;
  mOriginY = cy;

  gfxMatrix matrix(1, 0, 0, 1, cx, cy);
  matrix.Rotate(angle * radPerDegree);
  matrix.Translate(gfxPoint(-cx, -cy));

  NS_REMOVE_SVGVALUE_OBSERVER(mMatrix);
  mMatrix->SetA(static_cast<float>(matrix.xx));
  mMatrix->SetB(static_cast<float>(matrix.yx));
  mMatrix->SetC(static_cast<float>(matrix.xy));
  mMatrix->SetD(static_cast<float>(matrix.yy));
  mMatrix->SetE(static_cast<float>(matrix.x0));
  mMatrix->SetF(static_cast<float>(matrix.y0));
  NS_ADD_SVGVALUE_OBSERVER(mMatrix);

  DidModify();
  return NS_OK;
}
/* void setMatrix (in nsIDOMSVGMatrix matrix); */
NS_IMETHODIMP nsSVGTransform::SetMatrix(nsIDOMSVGMatrix *matrix)
{
  float a, b, c, d, e, f;

  if (!matrix)
    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;

  WillModify();

  mType = SVG_TRANSFORM_MATRIX;
  mAngle = 0.0f;
  
  matrix->GetA(&a);
  matrix->GetB(&b);
  matrix->GetC(&c);
  matrix->GetD(&d);
  matrix->GetE(&e);
  matrix->GetF(&f);

  NS_REMOVE_SVGVALUE_OBSERVER(mMatrix);
  mMatrix->SetA(a);
  mMatrix->SetB(b);
  mMatrix->SetC(c);
  mMatrix->SetD(d);
  mMatrix->SetE(e);
  mMatrix->SetF(f);
  NS_ADD_SVGVALUE_OBSERVER(mMatrix);

  DidModify();
  return NS_OK;
}
void
nsSVGLengthList::RemoveElementAt(PRInt32 index)
{
  WillModify();
  nsISVGLength* length = ElementAt(index);
  NS_ASSERTION(length, "null length");
  NS_REMOVE_SVGVALUE_OBSERVER(length);
  mLengths.RemoveElementAt(index);
  NS_RELEASE(length);
  DidModify();
}
void
nsSVGLengthList::ReleaseLengths()
{
  WillModify();
  PRInt32 count = mLengths.Count();
  for (PRInt32 i = 0; i < count; ++i) {
    nsISVGLength* length = ElementAt(i);
    length->SetContext(nsnull, 0);
    NS_REMOVE_SVGVALUE_OBSERVER(length);
    NS_RELEASE(length);
  }
  mLengths.Clear();
  DidModify();
}
/* void setScale (in float sx, in float sy); */
NS_IMETHODIMP nsSVGTransform::SetScale(float sx, float sy)
{
  NS_ENSURE_FINITE2(sx, sy, NS_ERROR_ILLEGAL_VALUE);

  WillModify();
  
  mType = SVG_TRANSFORM_SCALE;
  mAngle = 0.0f;
  NS_REMOVE_SVGVALUE_OBSERVER(mMatrix);
  mMatrix->SetA(sx);
  mMatrix->SetB(0.0f);
  mMatrix->SetC(0.0f);
  mMatrix->SetD(sy);
  mMatrix->SetE(0.0f);
  mMatrix->SetF(0.0f);
  NS_ADD_SVGVALUE_OBSERVER(mMatrix);

  DidModify();
  return NS_OK;
}
/* void setTranslate (in float tx, in float ty); */
NS_IMETHODIMP nsSVGTransform::SetTranslate(float tx, float ty)
{
  NS_ENSURE_FINITE2(tx, ty, NS_ERROR_ILLEGAL_VALUE);

  WillModify();
  
  mType = SVG_TRANSFORM_TRANSLATE;
  mAngle = 0.0f;
  NS_REMOVE_SVGVALUE_OBSERVER(mMatrix);
  mMatrix->SetA(1.0f);
  mMatrix->SetB(0.0f);
  mMatrix->SetC(0.0f);
  mMatrix->SetD(1.0f);
  mMatrix->SetE(tx);
  mMatrix->SetF(ty);
  NS_ADD_SVGVALUE_OBSERVER(mMatrix);

  DidModify();
  return NS_OK;
}
nsSVGTransform::~nsSVGTransform()
{
  NS_REMOVE_SVGVALUE_OBSERVER(mMatrix);
}