/* 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::AppendElement(nsISVGLength* aElement)
{
  WillModify();
  NS_ADDREF(aElement);
  
  // The SVG specs state that 'if newItem is already in a list, it
  // is removed from its previous list before it is inserted into this
  // list':
  //  aElement->SetListOwner(this);
  
  aElement->SetContext(mContext, mCtxType);
  mLengths.AppendElement((void*)aElement);
  NS_ADD_SVGVALUE_OBSERVER(aElement);
  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;
}
nsresult nsSVGTransform::Init()
{
  nsresult rv = NS_NewSVGMatrix(getter_AddRefs(mMatrix));
  NS_ADD_SVGVALUE_OBSERVER(mMatrix);
  return rv;
}