/*
 * Go2ProfileStripZ.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/zGo2ProfileStripZ.h>
#include <z/zGo2ProfileTypes.h>
#include <z/zGo2System.h>
#include <string.h>

/*
 * Go2ProfileStripZ Class
 */

GO2_EXPORT(Go2Status) Go2ProfileStripZ_Construct(Go2ProfileStripZ* measurement, Go2UInt32 id, Go2Object system)
{
    Go2ProfileStripZ output = zNIL; 
    Go2Status status = GO2_OK; 

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

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

    return GO2_OK; 
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_Init(Go2ProfileStripZ measurement, Go2UInt32 id, Go2Object system)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement);

    zCHECK(Go2Measurement_Init(measurement, GO2_TYPE_PROFILE_STRIP_Z, id, system)); 

    obj->Release = Go2ProfileStripZ_VRelease; 
    obj->Read = Go2ProfileStripZ_VRead; 
    obj->Write = Go2ProfileStripZ_VWrite; 

    obj->baseType = GO2_PROFILE_STRIP_BASE_NONE;
    obj->location = GO2_PROFILE_STRIP_LOCATION_LEFT;
    obj->leftEdgeType = 0xF; //enable all
    obj->rightEdgeType = 0xF; //enable all
    obj->tiltEnabled = 1;
    obj->selectType = GO2_PROFILE_STRIP_SELECT_BEST;
    obj->selectN = 0; //not applicable with BEST, set it anyways
    obj->transitionWidth = 2.0;
    obj->supportWidth = 5.0;
    obj->edgeHeightMin = 2.0;
    obj->voidMax = 0;
    obj->widthMin = 0;

    zCHECK(Go2ProfileArea_Construct(&obj->area, system));       

    return GO2_OK; 
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_VRelease(Go2ProfileStripZ measurement)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement);

    zCHECK(Go2Object_Destroy(obj->area)); 

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

GO2_EXPORT(Go2Status) Go2ProfileStripZ_VRead(Go2ProfileStripZ measurement, zXml xml, zXmlItem item)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 
    zChar* text = zNULL;
    z32u textCapacity = GO2_MEASUREMENT_SOURCE_TEXT_CAPACITY; 

    zXmlItem areaItem = zNIL; 

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

    zCHECK(zCalloc(&text, textCapacity, sizeof(zChar)));
    zCHECK(zXml_ChildText(xml, item, "SourceOptions", text, textCapacity)); 
    zCHECK(Go2OptionList_ParseList(text, obj->sourceOptions));  

    zCHECK(zXml_Child32u(xml, item, "Source", &obj->source)); 
    
    zCHECK(zXml_Child32s(xml, item, "BaseType", (z32s*) &obj->baseType)); 
    zCHECK(zXml_Child32s(xml, item, "Location", (z32s*) &obj->location)); 
    zCHECK(zXml_Child32u(xml, item, "LeftEdgeType", &obj->leftEdgeType)); 
    zCHECK(zXml_Child32u(xml, item, "RightEdgeType", &obj->rightEdgeType)); 
    zCHECK(zXml_Child32s(xml, item, "TiltEnabled", &obj->tiltEnabled)); 
    zCHECK(zXml_Child32s(xml, item, "SelectType", (z32s*) &obj->selectType));
    zCHECK(zXml_Child32u(xml, item, "SelectN", &obj->selectN));
    zCHECK(zXml_Child64f(xml, item, "EdgeSupportWidth", &obj->supportWidth));
    zCHECK(zXml_Child64f(xml, item, "EdgeTransitionWidthMax", &obj->transitionWidthMax));
    zCHECK(zXml_Child64f(xml, item, "EdgeTransitionWidth", &obj->transitionWidth));
    zCHECK(zXml_Child64f(xml, item, "VoidMaxLimitMax", &obj->voidMaxLimitMax));
    zCHECK(zXml_Child64f(xml, item, "VoidMax", &obj->voidMax));
    zCHECK(zXml_Child64f(xml, item, "WidthMin", &obj->widthMin));
    zCHECK(zXml_Child64f(xml, item, "EdgeHeightMin", &obj->edgeHeightMin));

    zCHECK(!zIS_NIL(areaItem = zXml_Child(xml, item, "Area"))); 
    zCHECK(Go2ProfileArea_Read(obj->area, xml, areaItem)); 

    zCHECK(zFree(text));

    return GO2_OK; 
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_VWrite(Go2ProfileStripZ measurement, zXml xml, zXmlItem item)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 
    zXmlItem areaItem = zNIL; 

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

    zCHECK(zXml_SetChild32u(xml, item, "Source", obj->source)); 

    zCHECK(zXml_SetChild32s(xml, item, "BaseType", obj->baseType)); 
    zCHECK(zXml_SetChild32s(xml, item, "Location", obj->location));
    zCHECK(zXml_SetChild32u(xml, item, "LeftEdgeType", obj->leftEdgeType)); 
    zCHECK(zXml_SetChild32u(xml, item, "RightEdgeType", obj->rightEdgeType)); 
    zCHECK(zXml_SetChild32s(xml, item, "TiltEnabled", obj->tiltEnabled)); 
    zCHECK(zXml_SetChild32s(xml, item, "SelectType", obj->selectType)); 
    zCHECK(zXml_SetChild32u(xml, item, "SelectN", obj->selectN)); 
    zCHECK(zXml_SetChild64f(xml, item, "EdgeSupportWidth", obj->supportWidth));
    zCHECK(zXml_SetChild64f(xml, item, "EdgeTransitionWidth", obj->transitionWidth));
    zCHECK(zXml_SetChild64f(xml, item, "VoidMax", obj->voidMax));
    zCHECK(zXml_SetChild64f(xml, item, "WidthMin", obj->widthMin));
    zCHECK(zXml_SetChild64f(xml, item, "EdgeHeightMin", obj->edgeHeightMin));

    zCHECK(zXml_AddItem(xml, item, "Area", &areaItem)); 
    zCHECK(Go2ProfileArea_Write(obj->area, xml, areaItem)); 

    return GO2_OK; 
}


GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetId(Go2ProfileStripZ measurement, Go2UInt32 id)
{
    return Go2Measurement_SetId(measurement, id);     
}

GO2_EXPORT(Go2UInt32) Go2ProfileStripZ_Id(Go2ProfileStripZ measurement)
{
    return Go2Measurement_Id(measurement);     
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetName(Go2ProfileStripZ measurement, const Go2Char* name)
{
    return Go2Measurement_SetName(measurement, name);     
}

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

GO2_EXPORT(Go2UInt32) Go2ProfileStripZ_SourceOptionCount(Go2ProfileStripZ measurement)
{
    return Go2Measurement_SourceOptionCount(measurement);     
}

GO2_EXPORT(Go2ProfileSource) Go2ProfileStripZ_SourceOptionAt(Go2ProfileStripZ measurement, Go2UInt32 index)
{
    return Go2Measurement_SourceOptionAt(measurement, index);     
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetSource(Go2ProfileStripZ measurement, Go2ProfileSource source)
{
    return Go2Measurement_SetSource(measurement, source);     
}

GO2_EXPORT(Go2ProfileSource) Go2ProfileStripZ_Source(Go2ProfileStripZ measurement)
{
    return Go2Measurement_Source(measurement);     
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetDecisionMin(Go2ProfileStripZ measurement, Go2Double min)
{
    return Go2Measurement_SetDecisionMin(measurement, min);     
}

GO2_EXPORT(Go2Double) Go2ProfileStripZ_DecisionMin(Go2ProfileStripZ measurement)
{
    return Go2Measurement_DecisionMin(measurement);     
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetDecisionMax(Go2ProfileStripZ measurement, Go2Double max)
{
    return Go2Measurement_SetDecisionMax(measurement, max);     
}

GO2_EXPORT(Go2Double) Go2ProfileStripZ_DecisionMax(Go2ProfileStripZ measurement)
{
    return Go2Measurement_DecisionMax(measurement);     
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_EnableHold(Go2ProfileStripZ measurement, Go2Bool enable)
{
    return Go2Measurement_EnableHold(measurement, enable);  
} 

GO2_EXPORT(Go2Bool) Go2ProfileStripZ_HoldEnabled(Go2ProfileStripZ measurement)
{
    return Go2Measurement_HoldEnabled(measurement);  
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_EnableSmoothing(Go2ProfileStripZ measurement, Go2Bool enable)
{
    return Go2Measurement_EnableSmoothing(measurement, enable);  
} 

GO2_EXPORT(Go2Bool) Go2ProfileStripZ_SmoothingEnabled(Go2ProfileStripZ measurement)
{
    return Go2Measurement_SmoothingEnabled(measurement);  
} 

GO2_EXPORT(Go2UInt32) Go2ProfileStripZ_SmoothingWindowMin(Go2ProfileStripZ measurement)
{
    return Go2Measurement_SmoothingWindowMin(measurement);  
} 

GO2_EXPORT(Go2UInt32) Go2ProfileStripZ_SmoothingWindowMax(Go2ProfileStripZ measurement)
{
    return Go2Measurement_SmoothingWindowMax(measurement);  
} 

GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetSmoothingWindow(Go2ProfileStripZ measurement, Go2UInt32 window)
{
    return Go2Measurement_SetSmoothingWindow(measurement, window);  
} 

GO2_EXPORT(Go2UInt32) Go2ProfileStripZ_SmoothingWindow(Go2ProfileStripZ measurement)
{
    return Go2Measurement_SmoothingWindow(measurement);  
} 

GO2_EXPORT(Go2ProfileArea) Go2ProfileStripZ_Area(Go2ProfileStripZ measurement)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 
    return obj->area;  
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetBaseType(Go2ProfileStripZ measurement, Go2ProfileStripBaseType baseType)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 

    zCHECK(Go2System_CheckConfigurable(obj->system)); 
    obj->baseType = baseType; 
    zCHECK(Go2System_SetModified(obj->system)); 

    return GO2_OK;      
}
 
GO2_EXPORT(Go2ProfileStripBaseType) Go2ProfileStripZ_BaseType(Go2ProfileStripZ measurement)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 
    return obj->baseType;      
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetLocation(Go2ProfileStripZ measurement, Go2ProfileStripLocation location)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 

    zCHECK(Go2System_CheckConfigurable(obj->system)); 
    obj->location = location; 
    zCHECK(Go2System_SetModified(obj->system)); 

    return GO2_OK;      
}
 
GO2_EXPORT(Go2Status) Go2ProfileStripZ_EnableLeftEdgeType(Go2ProfileStripZ measurement, Go2ProfileStripEdgeType type, Go2Bool enable)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 

    zCHECK(Go2System_CheckConfigurable(obj->system)); 
    if(enable)
    {
        obj->leftEdgeType |= (Go2UInt32)type; 
    }
    else
    {
        obj->leftEdgeType &= ~((Go2UInt32)type); 
    }
    zCHECK(Go2System_SetModified(obj->system)); 

    return GO2_OK;
}

GO2_EXPORT(Go2Bool) Go2ProfileStripZ_LeftEdgeTypeEnabled(Go2ProfileStripZ measurement, Go2ProfileStripEdgeType type)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 
    return (obj->leftEdgeType & (Go2UInt32)type) != 0;   
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_EnableRightEdgeType(Go2ProfileStripZ measurement, Go2ProfileStripEdgeType type, Go2Bool enable)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 

    zCHECK(Go2System_CheckConfigurable(obj->system)); 
    if(enable)
    {
        obj->rightEdgeType |= (Go2UInt32)type; 
    }
    else
    {
        obj->rightEdgeType &= ~((Go2UInt32)type); 
    }
    zCHECK(Go2System_SetModified(obj->system)); 

    return GO2_OK;
}

GO2_EXPORT(Go2Bool) Go2ProfileStripZ_RightEdgeTypeEnabled(Go2ProfileStripZ measurement, Go2ProfileStripEdgeType type)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 
    return (obj->rightEdgeType & (Go2UInt32)type) != 0;   
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_EnableTilt(Go2ProfileStripZ measurement, Go2Bool enable)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 

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

    return GO2_OK;
}

GO2_EXPORT(Go2Bool) Go2ProfileStripZ_TiltEnabled(Go2ProfileStripZ measurement)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 
    return obj->tiltEnabled;   
}

GO2_EXPORT(Go2ProfileStripLocation) Go2ProfileStripZ_Location(Go2ProfileStripZ measurement)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 
    return obj->location;      
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetSelectType(Go2ProfileStripZ measurement, Go2ProfileStripSelectType type)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 

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

    return GO2_OK;      
}
 
GO2_EXPORT(Go2ProfileStripSelectType) Go2ProfileStripZ_SelectType(Go2ProfileStripZ measurement)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 
    return obj->selectType;      
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetSelectN(Go2ProfileStripZ measurement, Go2UInt32 n)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 

    zCHECK(Go2System_CheckConfigurable(obj->system)); 
    obj->selectN = n; 
    zCHECK(Go2System_SetModified(obj->system)); 

    return GO2_OK;      
}
 
GO2_EXPORT(Go2UInt32) Go2ProfileStripZ_SelectN(Go2ProfileStripZ measurement)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 
    return obj->selectN;      
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetEdgeSupportWidth(Go2ProfileStripZ measurement, Go2Double width)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 

    zCHECK(Go2System_CheckConfigurable(obj->system)); 
    obj->supportWidth = width; 
    zCHECK(Go2System_SyncConfig(obj->system)); 

    return GO2_OK;      
}
 
GO2_EXPORT(Go2Double) Go2ProfileStripZ_EdgeSupportWidth(Go2ProfileStripZ measurement)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 
    return obj->supportWidth;      
}

GO2_EXPORT(Go2Double) Go2ProfileStripZ_EdgeTransitionWidthMax(Go2ProfileStripZ measurement)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 
    return obj->transitionWidthMax;      
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetEdgeTransitionWidth(Go2ProfileStripZ measurement, Go2Double width)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 

    zCHECK(Go2System_Set64f(obj->system, &obj->transitionWidth, width, 0, obj->transitionWidthMax));
    zCHECK(Go2System_SyncConfig(obj->system)); 

    return GO2_OK;      
}
 
GO2_EXPORT(Go2Double) Go2ProfileStripZ_EdgeTransitionWidth(Go2ProfileStripZ measurement)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 
    return obj->transitionWidth;      
}

GO2_EXPORT(Go2Double) Go2ProfileStripZ_VoidMaxLimitMax(Go2ProfileStripZ measurement)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 
    return obj->voidMaxLimitMax;      
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetVoidMax(Go2ProfileStripZ measurement, Go2Double width)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 

    zCHECK(Go2System_CheckConfigurable(obj->system)); 
    zCHECK(Go2System_Set64f(obj->system, &obj->voidMax, width, 0, obj->voidMaxLimitMax));
    zCHECK(Go2System_SetModified(obj->system)); 

    return GO2_OK;      
}
 
GO2_EXPORT(Go2Double) Go2ProfileStripZ_VoidMax(Go2ProfileStripZ measurement)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 
    return obj->voidMax;      
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetWidthMin(Go2ProfileStripZ measurement, Go2Double width)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 

    zCHECK(Go2System_CheckConfigurable(obj->system)); 
    obj->widthMin = width; 
    zCHECK(Go2System_SetModified(obj->system)); 

    return GO2_OK;      
}
 
GO2_EXPORT(Go2Double) Go2ProfileStripZ_WidthMin(Go2ProfileStripZ measurement)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 
    return obj->widthMin;      
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetEdgeHeightMin(Go2ProfileStripZ measurement, Go2Double height)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 

    zCHECK(Go2System_CheckConfigurable(obj->system)); 
    obj->edgeHeightMin = height; 
    zCHECK(Go2System_SetModified(obj->system)); 

    return GO2_OK;      
}
 
GO2_EXPORT(Go2Double) Go2ProfileStripZ_EdgeHeightMin(Go2ProfileStripZ measurement)
{
    Go2ProfileStripZClass* obj = zHANDLE_POINTER(measurement); 
    return obj->edgeHeightMin;      
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetScale(Go2ProfileStripZ measurement, Go2Double scale){
    return Go2Measurement_SetScale(measurement, scale);
}

GO2_EXPORT(Go2Double) Go2ProfileStripZ_Scale(Go2ProfileStripZ measurement){
    return Go2Measurement_Scale(measurement);
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetOffset(Go2ProfileStripZ measurement, Go2Double offset){
    return Go2Measurement_SetOffset(measurement, offset);
}

GO2_EXPORT(Go2Double) Go2ProfileStripZ_Offset(Go2ProfileStripZ measurement){
    return Go2Measurement_Offset(measurement);
}

GO2_EXPORT(Go2UInt32) Go2ProfileStripZ_LinkOptionCount(Go2ProfileStripZ measurement)
{
    return Go2Measurement_LinkOptionCount(measurement);
}

GO2_EXPORT(Go2UInt32) Go2ProfileStripZ_LinkOptionAt(Go2ProfileStripZ measurement, Go2UInt32 index)
{
    return Go2Measurement_LinkOptionAt(measurement, index);
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_EnableLink(Go2ProfileStripZ measurement, Go2Bool enable)  
{
    return Go2Measurement_EnableLink(measurement, enable);  
}

GO2_EXPORT(Go2Bool) Go2ProfileStripZ_LinkEnabled(Go2ProfileStripZ measurement)  
{
    return Go2Measurement_LinkEnabled(measurement);  
}

GO2_EXPORT(Go2Status) Go2ProfileStripZ_SetLink(Go2ProfileStripZ measurement, Go2UInt32 link) 
{
    return Go2Measurement_SetLink(measurement, link); 
}

GO2_EXPORT(Go2UInt32) Go2ProfileStripZ_Link(Go2ProfileStripZ measurement) 
{
    return Go2Measurement_Link(measurement); 
}
