/*
 * Go2PartOpeningX.c
 * 
 * Gocator system communication library
 * Copyright (C) 2013 by LMI Technologies Inc.
 * 
 * Licensed under The MIT License.
 * Redistributions of files must retain the above copyright notice.
 */

#include <z/Go2Measurements/zGo2PartOpeningX.h>
#include <z/zGo2PartTypes.h>
#include <z/zGo2System.h>
#include <string.h>

/*
 * Go2PartOpeningX Class 
 */

GO2_EXPORT(Go2Status) Go2PartOpeningX_Construct(Go2PartOpeningX* measurement, Go2UInt32 id, Go2Object system)
{
    Go2PartOpeningX output = zNIL; 
    Go2Status status = zOK; 

    zCHECK(zCalloc(&output, 1, sizeof(Go2PartOpeningXClass))); 

    if (!zSUCCESS(status = Go2PartOpeningX_Init(output, id, system)))
    {
        zCHECK(Go2Object_Destroy(output)); 
        return status; 
    }

    *measurement = output; 

    return GO2_OK; 
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_Init(Go2PartOpeningX measurement, Go2UInt32 id, Go2Object system)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement);
    z32u i; 

    zCHECK(Go2PartMeasurement_Init(measurement, GO2_TYPE_PART_OPENING_X, id, system)); 

    obj->Release = Go2PartOpeningX_VRelease;
    obj->Read = Go2PartOpeningX_VRead; 
    obj->Write = Go2PartOpeningX_VWrite; 

    obj->openingType = GO2_PART_OPENING_TYPE_ROUNDED_SLOT;

    obj->nominalLength = 20.0;
    obj->nominalWidth = 10.0;
    obj->nominalAngle = 0.0;
    obj->nominalRadius = 5.0;
    obj->lengthTolerance = 4.0;
    obj->widthTolerance = 2.0;
    obj->angleTolerance = 5.0;
    obj->partialDetectionEnabled = GO2_FALSE;

    for (i = 0; i < zCOUNT(obj->refRegions); ++i)
    {
        zCHECK(Go2PartRegion2d_Construct(&obj->refRegions[i], system));
    }
    //construct all ref areas, but initialize the measurement to only use 2
    obj->refRegionCount = 2;

    obj->refRegionsEnabled = GO2_FALSE;
    obj->autoRefRegionEnabled = GO2_TRUE;
    obj->autoTiltCorrectionEnabled = GO2_TRUE;
    obj->tiltXAngle = 0.0;
    obj->tiltYAngle = 0.0;

    return GO2_OK; 
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_VRelease(Go2PartOpeningX measurement)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement);
    z32u i; 

    for (i = 0; i < zCOUNT(obj->refRegions); ++i)
    {
        zCHECK(Go2Object_Destroy(obj->refRegions[i])); 
    }

    zCHECK(Go2PartMeasurement_VRelease(measurement));  
        
    return GO2_OK; 
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_VRead(Go2PartOpeningX measurement, zXml xml, zXmlItem item)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement);
    zXmlItem regionItem = zNIL;

    zCHECK(Go2PartMeasurement_VRead(measurement, xml, item)); 

    obj->refRegionCount = 0; 
    //ensure we at least have one refArea
    zCHECK(!zIS_NIL(regionItem = zXml_Child(xml, item, "RefRegions/RefRegion")));     
    while (!zIS_NIL(regionItem))
    {
        zCHECK(Go2PartRegion2d_Read(obj->refRegions[obj->refRegionCount], xml, regionItem));  
        obj->refRegionCount++;  
        regionItem = zXml_NextSibling(xml, regionItem);
    }
    
    zCHECK(zXml_Child32s(xml, item, "Type", (z32s*) &obj->openingType)); 

    zCHECK(zXml_Child64f(xml, item, "NominalRadius", &obj->nominalRadius)); 
    zCHECK(zXml_Child64f(xml, item, "NominalLength", &obj->nominalLength)); 
    zCHECK(zXml_Child64f(xml, item, "NominalWidth", &obj->nominalWidth)); 
    zCHECK(zXml_Child64f(xml, item, "NominalAngle", &obj->nominalAngle)); 
    zCHECK(zXml_Child64f(xml, item, "LengthTolerance", &obj->lengthTolerance)); 
    zCHECK(zXml_Child64f(xml, item, "WidthTolerance", &obj->widthTolerance)); 
    zCHECK(zXml_Child64f(xml, item, "AngleTolerance", &obj->angleTolerance)); 
    zCHECK(zXml_Child32s(xml, item, "PartialDetectionEnabled", &obj->partialDetectionEnabled));

    zCHECK(zXml_Child32s(xml, item, "RefRegionsEnabled", &obj->refRegionsEnabled));
    zCHECK(zXml_Child32s(xml, item, "AutoRefRegionEnabled", &obj->autoRefRegionEnabled));
    zCHECK(zXml_Child32s(xml, item, "AutoTiltCorrectionEnabled", &obj->autoTiltCorrectionEnabled));
    zCHECK(zXml_Child64f(xml, item, "TiltXAngle", &obj->tiltXAngle)); 
    zCHECK(zXml_Child64f(xml, item, "TiltYAngle", &obj->tiltYAngle)); 

    return GO2_OK; 
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_VWrite(Go2PartOpeningX  measurement, zXml xml, zXmlItem item)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement);
    zXmlItem regionItem = zNIL;
    zXmlItem refRegionItem = zNIL;
    z32u i; 

    zCHECK(Go2PartMeasurement_VWrite(measurement, xml, item)); 

    zCHECK(zXml_AddItem(xml, item, "RefRegions", &refRegionItem));  
    for (i = 0; i < obj->refRegionCount; ++i)
    {
        zCHECK(zXml_AddItem(xml, refRegionItem, "RefRegion", &regionItem)); 
        zCHECK(Go2PartRegion2d_Write(obj->refRegions[i], xml, regionItem)); 
    }

    zCHECK(zXml_SetChild32s(xml, item, "Type", (z32s) obj->openingType)); 

    zCHECK(zXml_SetChild64f(xml, item, "NominalRadius", obj->nominalRadius)); 
    zCHECK(zXml_SetChild64f(xml, item, "NominalLength", obj->nominalLength)); 
    zCHECK(zXml_SetChild64f(xml, item, "NominalWidth", obj->nominalWidth)); 
    zCHECK(zXml_SetChild64f(xml, item, "NominalAngle", obj->nominalAngle)); 
    zCHECK(zXml_SetChild64f(xml, item, "LengthTolerance", obj->lengthTolerance)); 
    zCHECK(zXml_SetChild64f(xml, item, "WidthTolerance", obj->widthTolerance)); 
    zCHECK(zXml_SetChild64f(xml, item, "AngleTolerance", obj->angleTolerance)); 
    zCHECK(zXml_SetChild32s(xml, item, "PartialDetectionEnabled", obj->partialDetectionEnabled)); 

    zCHECK(zXml_SetChild32s(xml, item, "RefRegionsEnabled", obj->refRegionsEnabled)); 
    zCHECK(zXml_SetChild32s(xml, item, "AutoRefRegionEnabled", obj->autoRefRegionEnabled)); 
    zCHECK(zXml_SetChild32s(xml, item, "AutoTiltCorrectionEnabled", obj->autoTiltCorrectionEnabled)); 
    zCHECK(zXml_SetChild64f(xml, item, "TiltXAngle", obj->tiltXAngle)); 
    zCHECK(zXml_SetChild64f(xml, item, "TiltYAngle", obj->tiltYAngle)); 

    return GO2_OK; 
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetId(Go2PartOpeningX measurement, Go2UInt32 id)
{
    return Go2Measurement_SetId(measurement, id); 
}

GO2_EXPORT(Go2UInt32) Go2PartOpeningX_Id(Go2PartOpeningX measurement)
{
    return Go2Measurement_Id(measurement); 
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetName(Go2PartOpeningX measurement, const Go2Char* name)
{
    return Go2Measurement_SetName(measurement, name); 
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_Name(Go2PartOpeningX measurement, Go2Char* name, Go2UInt32 capacity)
{
    return Go2Measurement_Name(measurement, name, capacity); 
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetDecisionMin(Go2PartOpeningX measurement, Go2Double min)
{
    return Go2Measurement_SetDecisionMin(measurement, min); 
}

GO2_EXPORT(Go2Double) Go2PartOpeningX_DecisionMin(Go2PartOpeningX measurement)
{
    return Go2Measurement_DecisionMin(measurement); 
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetDecisionMax(Go2PartOpeningX measurement, Go2Double max)
{
    return Go2Measurement_SetDecisionMax(measurement, max); 
}

GO2_EXPORT(Go2Double) Go2PartOpeningX_DecisionMax(Go2PartOpeningX measurement)
{
    return Go2Measurement_DecisionMax(measurement); 
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_EnableHold(Go2PartOpeningX measurement, Go2Bool enable)
{
    return Go2Measurement_EnableHold(measurement, enable);  
} 

GO2_EXPORT(Go2Bool) Go2PartOpeningX_HoldEnabled(Go2PartOpeningX measurement)
{
    return Go2Measurement_HoldEnabled(measurement);  
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_EnableSmoothing(Go2PartOpeningX measurement, Go2Bool enable)
{
    return Go2Measurement_EnableSmoothing(measurement, enable);  
} 

GO2_EXPORT(Go2Bool) Go2PartOpeningX_SmoothingEnabled(Go2PartOpeningX measurement)
{
    return Go2Measurement_SmoothingEnabled(measurement);  
} 

GO2_EXPORT(Go2UInt32) Go2PartOpeningX_SmoothingWindowMin(Go2PartOpeningX measurement)
{
    return Go2Measurement_SmoothingWindowMin(measurement);  
} 

GO2_EXPORT(Go2UInt32) Go2PartOpeningX_SmoothingWindowMax(Go2PartOpeningX measurement)
{
    return Go2Measurement_SmoothingWindowMax(measurement);  
} 

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetSmoothingWindow(Go2PartOpeningX measurement, Go2UInt32 window)
{
    return Go2Measurement_SetSmoothingWindow(measurement, window);  
} 

GO2_EXPORT(Go2UInt32) Go2PartOpeningX_SmoothingWindow(Go2PartOpeningX measurement)
{
    return Go2Measurement_SmoothingWindow(measurement);  
} 

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetType(Go2PartOpeningX measurement, Go2PartOpeningType type)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement);

    zCHECK(Go2System_CheckConfigurable(obj->system)); 
    obj->openingType = type; 
    zCHECK(Go2System_SetModified(obj->system)); 

    return GO2_OK; 
}

GO2_EXPORT(Go2PartOpeningType) Go2PartOpeningX_Type(Go2PartOpeningX measurement)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement);
    return obj->openingType; 
}

GO2_EXPORT(Go2UInt32) Go2PartOpeningX_RefRegionCount(Go2PartOpeningX measurement)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 
    return obj->refRegionCount;      
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetRefRegionCount(Go2PartOpeningX measurement, Go2UInt32 count)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 
    Go2Status status = GO2_OK;

    if(count > zCOUNT(obj->refRegions)){
        return GO2_ERROR_PARAMETER;
    }
    zCHECK(Go2System_CheckConfigurable(obj->system)); 
    status = Go2System_Set32u(obj->system, &obj->refRegionCount, count, 1, GO2_MAX_REF_REGIONS); 
    zCHECK(Go2System_SetModified(obj->system)); 

    return status;      
}

GO2_EXPORT(Go2PartRegion2d) Go2PartOpeningX_RefRegionAt(Go2PartOpeningX measurement, Go2UInt32 index)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 

    return obj->refRegions[index];      
}

GO2_EXPORT(Go2Double) Go2PartOpeningX_NominalLength(Go2PartOpeningX measurement)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 
    return obj->nominalLength;      
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetNominalLength(Go2PartOpeningX measurement, Go2Double radius)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 

    return Go2System_Set64f(obj->system, &obj->nominalLength, radius, 0.0, z64F_MAX);        
}

GO2_EXPORT(Go2Double) Go2PartOpeningX_NominalWidth(Go2PartOpeningX measurement)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 
    return obj->nominalWidth;      
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetNominalWidth(Go2PartOpeningX measurement, Go2Double radius)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 

    return Go2System_Set64f(obj->system, &obj->nominalWidth, radius, 0.0, z64F_MAX);        
}

GO2_EXPORT(Go2Double) Go2PartOpeningX_NominalAngle(Go2PartOpeningX measurement)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 
    return obj->nominalAngle;      
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetNominalAngle(Go2PartOpeningX measurement, Go2Double radius)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 

    return Go2System_Set64f(obj->system, &obj->nominalAngle, radius, -z64F_MAX, z64F_MAX);        
}

GO2_EXPORT(Go2Double) Go2PartOpeningX_NominalRadius(Go2PartOpeningX measurement)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 
    return obj->nominalRadius;      
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetNominalRadius(Go2PartOpeningX measurement, Go2Double radius)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 

    return Go2System_Set64f(obj->system, &obj->nominalRadius, radius, 0.0, z64F_MAX);        
}

GO2_EXPORT(Go2Double) Go2PartOpeningX_LengthTolerance(Go2PartOpeningX measurement)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 
    return obj->lengthTolerance;      
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetLengthTolerance(Go2PartOpeningX measurement, Go2Double tolerance)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 

    return Go2System_Set64f(obj->system, &obj->lengthTolerance, tolerance, 0.0, z64F_MAX);   
}

GO2_EXPORT(Go2Double) Go2PartOpeningX_WidthTolerance(Go2PartOpeningX measurement)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 
    return obj->widthTolerance;      
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetWidthTolerance(Go2PartOpeningX measurement, Go2Double tolerance)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 

    return Go2System_Set64f(obj->system, &obj->widthTolerance, tolerance, 0.0, z64F_MAX);   
}

GO2_EXPORT(Go2Double) Go2PartOpeningX_AngleTolerance(Go2PartOpeningX measurement)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 
    return obj->angleTolerance;      
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetAngleTolerance(Go2PartOpeningX measurement, Go2Double tolerance)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 

    return Go2System_Set64f(obj->system, &obj->angleTolerance, tolerance, 0.0, z64F_MAX);   
}

GO2_EXPORT(Go2Bool) Go2PartOpeningX_AutoRefRegionEnabled(Go2PartOpeningX measurement)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement);
    return obj->autoRefRegionEnabled; 
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_EnableAutoRefRegion(Go2PartOpeningX measurement, Go2Bool enable)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement);

    zCHECK(Go2System_CheckConfigurable(obj->system)); 
    obj->autoRefRegionEnabled = enable; 
    zCHECK(Go2System_SetModified(obj->system)); 

    return GO2_OK;
}

GO2_EXPORT(Go2Bool) Go2PartOpeningX_AutoTiltCorrectionEnabled(Go2PartOpeningX measurement)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement);
    return obj->autoTiltCorrectionEnabled; 
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_EnableAutoTiltCorrection(Go2PartOpeningX measurement, Go2Bool enable)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement);

    zCHECK(Go2System_CheckConfigurable(obj->system)); 
    obj->autoTiltCorrectionEnabled = enable; 
    zCHECK(Go2System_SetModified(obj->system)); 

    return GO2_OK;
}

GO2_EXPORT(Go2Double) Go2PartOpeningX_TiltXAngle(Go2PartOpeningX measurement)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement);
    return obj->tiltXAngle; 
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetTiltXAngle(Go2PartOpeningX measurement, Go2Double tiltXAngle)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 

    return Go2System_Set64f(obj->system, &obj->tiltXAngle, tiltXAngle, -z64F_MAX, z64F_MAX);   
}

GO2_EXPORT(Go2Double) Go2PartOpeningX_TiltYAngle(Go2PartOpeningX measurement)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement);
    return obj->tiltYAngle; 
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetTiltYAngle(Go2PartOpeningX measurement, Go2Double tiltYAngle)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 

    return Go2System_Set64f(obj->system, &obj->tiltYAngle, tiltYAngle, -z64F_MAX, z64F_MAX);   
}


GO2_EXPORT(Go2Status) Go2PartOpeningX_SetScale(Go2PartOpeningX measurement, Go2Double scale){
    return Go2Measurement_SetScale(measurement, scale);
}

GO2_EXPORT(Go2Double) Go2PartOpeningX_Scale(Go2PartOpeningX measurement){
    return Go2Measurement_Scale(measurement);
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetOffset(Go2PartOpeningX measurement, Go2Double offset){
    return Go2Measurement_SetOffset(measurement, offset);
}

GO2_EXPORT(Go2Double) Go2PartOpeningX_Offset(Go2PartOpeningX measurement){
    return Go2Measurement_Offset(measurement);
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_EnablePartialDetection(Go2PartOpeningX measurement, Go2Bool enabled) 
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement);

    zCHECK(Go2System_CheckConfigurable(obj->system)); 
    obj->partialDetectionEnabled = enabled;
    zCHECK(Go2System_SetModified(obj->system));

    return GO2_OK;
}

GO2_EXPORT(Go2Bool) Go2PartOpeningX_PartialDetectionEnabled(Go2Script measurement) 
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement); 

    return obj->partialDetectionEnabled;
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_EnableLink(Go2PartOpeningX measurement, Go2Bool enable)  
{
    return Go2Measurement_EnableLink(measurement, enable);  
}

GO2_EXPORT(Go2Bool) Go2PartOpeningX_LinkEnabled(Go2PartOpeningX measurement)  
{
    return Go2Measurement_LinkEnabled(measurement);  
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_SetLink(Go2PartOpeningX measurement, Go2UInt32 link) 
{
    return Go2Measurement_SetLink(measurement, link); 
}

GO2_EXPORT(Go2UInt32) Go2PartOpeningX_Link(Go2PartOpeningX measurement) 
{
    return Go2Measurement_Link(measurement); 
}

GO2_EXPORT(Go2PartRegion3d) Go2PartOpeningX_Region(Go2PartOpeningX measurement)
{
    return Go2PartMeasurement_Region(measurement);
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_EnableRegion(Go2PartOpeningX measurement, Go2Bool enable)  
{
    return Go2PartMeasurement_EnableRegion(measurement, enable);  
}

GO2_EXPORT(Go2Bool) Go2PartOpeningX_RegionEnabled(Go2PartOpeningX measurement)  
{
    return Go2PartMeasurement_RegionEnabled(measurement);  
}

GO2_EXPORT(Go2Bool) Go2PartOpeningX_RefRegionsEnabled(Go2PartOpeningX measurement)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement);

    return obj->refRegionsEnabled;
}

GO2_EXPORT(Go2Status) Go2PartOpeningX_EnableRefRegions(Go2PartOpeningX measurement, Go2Bool enable)
{
    Go2PartOpeningXClass* obj = zHANDLE_POINTER(measurement);

    zCHECK(Go2System_CheckConfigurable(obj->system)); 
    obj->refRegionsEnabled = enable;
    zCHECK(Go2System_SetModified(obj->system));

    return GO2_OK;
}

GO2_EXPORT(Go2UInt32) Go2PartOpeningX_LinkOptionCount(Go2PartOpeningX measurement)
{
    return Go2Measurement_LinkOptionCount(measurement);
}

GO2_EXPORT(Go2UInt32) Go2PartOpeningX_LinkOptionAt(Go2PartOpeningX measurement, Go2UInt32 index)
{
    return Go2Measurement_LinkOptionAt(measurement, index);
}
