/*
    PsychAllocOutStructArray()
    
    -If argument is optional we allocate the structure even if the argument is not present.  If this bothers you, 
    then check within the subfunction for the presense of a return argument before creating the struct array.  We
    allocate space regardeless of whether the argument is present because this is consistant with other "PsychAllocOut*" 
    functions which behave this way because in some situations subfunctions might derive returned results from values
    stored in an optional argument.
    
    -If position is -1 then don't attempt to return the created structure to the calling environment.  Instead just 
    allocate the structure and return it in pStruct.  This is how to create a structure which is embeded within another 
    structure using PsychSetStructArrayStructArray().  Note that we use -1 as the flag and not NULL because NULL is 0 and
    0 is reserved for future use as a reference to the subfunction name, of if none then the function name. 
    

*/
boolean PsychAllocOutStructArray(	int position, 
                                        PsychArgRequirementType isRequired, 
                                        int numElements,
                                        int numFields, 
                                        const char **fieldNames,  
                                        PsychGenericScriptType **pStruct)
{
    mxArray **mxArrayOut;
    int structArrayNumDims=2;
    int structArrayDims[2];
	PsychError matchError;
	Boolean putOut;
	
    
    structArrayDims[0]=1;
    structArrayDims[1]=numElements;
    
    if(position !=kPsychNoArgReturn){  //Return the result to both the C caller and the scripting environment.
        PsychSetReceivedArgDescriptor(position, PsychArgOut);
        PsychSetSpecifiedArgDescriptor(position, PsychArgOut, PsychArgType_structArray, isRequired, 1,1,numElements,numElements,0,0);
        *pStruct = mxCreateStructArray(structArrayNumDims, structArrayDims, numFields, fieldNames);
		matchError=PsychMatchDescriptors();
		putOut=PsychAcceptOutputArgumentDecider(isRequired, matchError);
		if(putOut){
			mxArrayOut = PsychGetOutArgMxPtr(position);
            *mxArrayOut=*pStruct;
		}
		return(putOut);
    }else{ //Return the result only to the C caller.  Ignore "required".    
        *pStruct = mxCreateStructArray(structArrayNumDims, structArrayDims, numFields, fieldNames);
        return(TRUE);
    }
            
}
/*
    PsychAllocOutCellArray()
    
    -If argument is optional we allocate the structure even if the argument is not present.  If this behavior bothers you, 
    then check within your code for the presense of a return argument before creating the struct array.  We
    allocate space regardeless of whether the argument is present because this is consistant with other "PsychAllocOut*" 
    functions which behave this way because in some situations subfunctions might derive returned results from values
    stored in an optional argument.
    
    -If position is -1 then don't attempt to return the created structure to the calling environment.  Instead just 
    allocate the structure and return it in pStruct.  This is how to create a structure which is embeded within another 
    structure using PsychSetStructArrayStructArray().  Note that we use -1 as the flag and not NULL because NULL is 0 and
    0 is reserved for future use as a reference to the subfunction name, of if none then the function name. 
    

*/
boolean PsychAllocOutCellVector(	int position, 
									PsychArgRequirementType isRequired, 
									int numElements,  
									PsychGenericScriptType **pCell)
{
    mxArray **mxArrayOut;
    int cellArrayNumDims=2;
    int cellArrayDims[2];
	PsychError matchError;
	Boolean putOut;

    
    cellArrayDims[0]=1;
    cellArrayDims[1]=numElements;
    
    if(position != kPsychNoArgReturn){  //Return the result to both the C caller and the scripting environment.
        PsychSetReceivedArgDescriptor(position, PsychArgOut);
        PsychSetSpecifiedArgDescriptor(position, PsychArgOut, PsychArgType_cellArray, isRequired, 1,1,numElements,numElements,0,0);
        *pCell = mxCreateCellArray(cellArrayNumDims, cellArrayDims);
        mxArrayOut = PsychGetOutArgMxPtr(position);
		matchError=PsychMatchDescriptors();
		putOut=PsychAcceptOutputArgumentDecider(isRequired, matchError);
		if(putOut)
            *mxArrayOut=*pCell;
        return(putOut);
    }else{ //Return the result only to the C caller, not to the calling environment.  Ignore "required".    
        *pCell = mxCreateCellArray(cellArrayNumDims, cellArrayDims);
        return(TRUE);
    }
            
}
/*
    PsychAllocInNativeString()

    
*/
boolean PsychAllocInNativeString(int position, PsychArgRequirementType isRequired, const PsychGenericScriptType **nativeString)
{
	PsychError  matchError;
	Boolean		acceptArg;
    
    PsychSetReceivedArgDescriptor(position, PsychArgIn);
    PsychSetSpecifiedArgDescriptor(position, PsychArgIn, PsychArgType_char, isRequired, 1, kPsychUnboundedArraySize,1, kPsychUnboundedArraySize,0, 1);
 	matchError=PsychMatchDescriptors();
	acceptArg=PsychAcceptInputArgumentDecider(isRequired, matchError);
	if(acceptArg)
            *nativeString= PsychGetInArgMxPtr(position);
    return(acceptArg);
}
/* 
    PsychAllocInCellVector() 


*/
psych_bool PsychAllocInNativeCellVector(int position, PsychArgRequirementType isRequired, const PsychGenericScriptType **cellVector)
{
	PsychError matchError;
	psych_bool acceptArg;

    PsychSetReceivedArgDescriptor(position, FALSE, PsychArgIn);
    PsychSetSpecifiedArgDescriptor(position, PsychArgIn, PsychArgType_cellArray, isRequired, 1, kPsychUnboundedArraySize,1, kPsychUnboundedArraySize,0, 1);
	matchError=PsychMatchDescriptors();
	acceptArg=PsychAcceptInputArgumentDecider(isRequired, matchError);
	if(acceptArg)
		*cellVector= PsychGetInArgMxPtr(position);
	return(acceptArg);
}
boolean PsychAssignOutStructArray(	int position, 
                                        PsychArgRequirementType isRequired,   
                                        PsychGenericScriptType *pStruct)
{
    mxArray **mxArrayOut;
	PsychError matchError;
	Boolean putOut;
        
    PsychSetReceivedArgDescriptor(position, PsychArgOut);
    PsychSetSpecifiedArgDescriptor(position, PsychArgOut, PsychArgType_structArray, isRequired, 1,1,0,kPsychUnboundedArraySize,0,0);
	matchError=PsychMatchDescriptors();
	putOut=PsychAcceptOutputArgumentDecider(isRequired, matchError);
	if(putOut){
		mxArrayOut = PsychGetOutArgMxPtr(position);
        *mxArrayOut=pStruct;
	}
	return(putOut);
}