/******************************************************************************
* CagdEdit.c - Editing tools of surfaces and Curves.			      *
*******************************************************************************
* Written by Gershon Elber, Sep. 91.					      *
******************************************************************************/

#include "cagd_loc.h"

/******************************************************************************
* Modify a single control point in the curve.				      *
******************************************************************************/
CagdCrvStruct *CagdEditSingleCrvPt(CagdCrvStruct *Crv, CagdCtlPtStruct *CtlPt,
						   int Index, CagdBType Write)
{
    CagdBType
	IsNotRational = !CAGD_IS_RATIONAL_CRV(Crv);
    int i,
	Length = Crv -> Length,
	MaxCoord = CAGD_NUM_OF_PT_COORD(Crv -> PType);
    CagdCrvStruct
	*NewCrv = Write ? CagdCrvCopy(Crv) : NULL;
    CagdRType
	**Points = Write ? NewCrv -> Points : Crv -> Points;

    if (Index < 0 || Index >= Length)
	FATAL_ERROR(CAGD_ERR_INDEX_NOT_IN_MESH);

    if (Write) {
	if (Crv -> PType != CtlPt -> PtType)
	    FATAL_ERROR(CAGD_ERR_PT_OR_LEN_MISMATCH);

	for (i = IsNotRational; i <= MaxCoord; i++)
	    Points[i][Index] = CtlPt -> Coords[i];
    }
    else {
        CtlPt -> PtType = Crv -> PType;

	for (i = IsNotRational; i <= MaxCoord; i++)
	    CtlPt -> Coords[i] = Points[i][Index];
    }

    return NewCrv;
}

/******************************************************************************
* Modify a single control point in the surface.				      *
 *****************************************************************************/
CagdSrfStruct *CagdEditSingleSrfPt(CagdSrfStruct *Srf, CagdCtlPtStruct *CtlPt,
				       int UIndex, int VIndex, CagdBType Write)
{
    CagdBType
	IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf);
    int i,
	ULength = Srf -> ULength,
	VLength = Srf -> VLength,
	MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType);
    CagdSrfStruct
	*NewSrf = Write ? CagdSrfCopy(Srf) : NULL;
    CagdRType
	**Points = Write ? NewSrf -> Points : Srf -> Points;

    if (UIndex < 0 || UIndex >= ULength ||
	VIndex < 0 || VIndex >= VLength)
	FATAL_ERROR(CAGD_ERR_INDEX_NOT_IN_MESH);

    if (Write) {
	if (Srf -> PType != CtlPt -> PtType)
	    FATAL_ERROR(CAGD_ERR_PT_OR_LEN_MISMATCH);

	for (i = IsNotRational; i <= MaxCoord; i++)
	    Points[i][CAGD_MESH_UV(NewSrf, UIndex, VIndex)] =
		CtlPt -> Coords[i];
    }
    else {
        CtlPt -> PtType = Srf -> PType;

	for (i = IsNotRational; i <= MaxCoord; i++)
	    CtlPt -> Coords[i] =
		Points[i][CAGD_MESH_UV(Srf, UIndex, VIndex)];
    }

    return NewSrf;
}
