/**
* To extract the argument of access or banked
*
* Input:
*	String	the whole argument
* 
* Return the value of access/banked
* Throw if value is invalid
*/
int extractAccessBanked(String *arguments){
	char location;
	char *returnChar;
	int returnInt;
	String *string;
	String *banked = stringNew(textNew("BANKED")); //1
	String *access = stringNew(textNew("ACCESS")); //0
	
	if(stringCharAt(arguments,0) == ',')
		stringRemoveChar(arguments);
		
	if(stringLength(arguments) == 0 ||stringCharAt(arguments,0) == ';')
		
		Throw(ERR_NO_ARGUMENT);
		
	stringTrimLeft(arguments);
	
	if(stringLength(arguments) == 0 ||stringCharAt(arguments,0) == ';')
		Throw(ERR_EMPTY_ARGUMENT);
		
	string = stringRemoveWordNotContaining(arguments,",;");
	
	stringTrim(string);
	
	if(stringLength(string) == 0){
		if(stringCharAt(arguments,0) == ',')
			stringRemoveChar(arguments);
		Throw(ERR_EMPTY_ARGUMENT);
	}
	
	else if(stringLength(string) == 6){
		
		if(stringIsEqual(string,banked))
			returnInt = 1;
		else if(stringIsEqual(string,access))
			returnInt = 0;
		else{
			returnChar = stringSubstringInChar(string,0,string->length);
			returnInt =  evaluate(returnChar);
		}
	}
	else{
		returnChar = stringSubstringInChar(string,0,string->length);
		returnInt = evaluate(returnChar);
	}
	
	if(stringCharAt(arguments,0) == ',')
		stringRemoveChar(arguments);
	
	free(string);
	return returnInt;

}
/**
* To extract the argument of location to save
*
* Input:
*	String	the whole argument
* 
* Return the value of the location
* Throw if value is invalid
*/
int extractDestination(String *arguments){
	
	
	char location;
	char *returnChar;
	int returnInt;
	String *string;
	
	if(stringCharAt(arguments,0) == ',')
		stringRemoveChar(arguments);
	
	if(stringLength(arguments) == 0 ||stringCharAt(arguments,0) == ';')
		
		Throw(ERR_NO_ARGUMENT);
		
	stringTrimLeft(arguments);
	
	if(stringLength(arguments) == 0 || stringCharAt(arguments,0)== ';')
		Throw(ERR_EMPTY_ARGUMENT);
		
	string = stringRemoveWordNotContaining(arguments,",;");
	stringTrim(string);
	
	if(stringLength(string) == 0){
		if(stringCharAt(arguments,0) == ',')
			stringRemoveChar(arguments);
		Throw(ERR_EMPTY_ARGUMENT);
	}
	
	else if(stringLength(string) == 1){
		location = stringCharAt(string,0);
		if(location == 'F')
			returnInt = 1;
		else if(location == 'W')
			returnInt = 0;
		else{
			returnChar = stringSubstringInChar(string,0,string->length);
			returnInt =  evaluate(returnChar);
		}
	}
	else{
		returnChar = stringSubstringInChar(string,0,string->length);
		returnInt = evaluate(returnChar);
	}
	
	
	free(string);
	return returnInt;
	

}//if f, return 1, w is 0
Text *stringSubstringInText(String *str, int relativePosition, int length){
	char *charStr = stringSubstringInChar(str, relativePosition, length);
	Text *text = textNew(charStr);
	free(charStr);
	
	return text;
}
/**
*	Top module to extract the whole string into final OpCode
*
* Input:
*	String	instructions,with appropriate arguments
* 
* Return OpCode in int type
*/
unsigned int interpret(String *instruction){
	stringTrimLeft(instruction);
	String *instString = stringRemoveWordNotContaining(instruction," ");
	char *instChar = stringSubstringInChar(instString,0,instString->length);
	instructionTable inst = getInstruction(instChar);
	
	if(inst.type == FDA_TYPE)
		return inst.opCode | FDA(instruction);
	else if(inst.type == FBA_TYPE)
		return inst.opCode | FBA(instruction);
	else if(inst.type == FA_TYPE)
		return inst.opCode | FA(instruction);
	else if(inst.type == FSFD_TYPE)
		return inst.opCode | FSFD(instruction);
	else if(inst.type == N_TYPE)
		return inst.opCode | N(instruction);
	else if(inst.type == NS_TYPE)
		return inst.opCode | NS(instruction);
	else if(inst.type == S_TYPE)
		return inst.opCode | S(instruction);
	else if(inst.type == K_TYPE)
		return inst.opCode | K(instruction);
	else if(inst.type == FK_TYPE)
		return inst.opCode | FK(instruction);
	else
		Throw(ERR_ILLEGAL_ARGUMENT);
}
/**
* To extract the argument of address
*
* Input:
*	String	the whole argument
* 
* Return the value of the address
* Throw if value is invalid
*/
int extractValue(String *arguments){
	
	char *returnChar;
	int returnInt;
	String *string;
	stringTrimLeft(arguments);
	
	if(stringCharAt(arguments,0) == ',')
		stringRemoveChar(arguments);
		
	if(stringCharAt(arguments,0) == ';' || stringLength(arguments) == 0)
		
		Throw(ERR_NO_ARGUMENT);
		
	string = stringRemoveWordNotContaining(arguments,",;");
	stringTrim(string);
	
	if(stringLength(string) == 0)
		Throw(ERR_EMPTY_ARGUMENT);
		
	returnChar = stringSubstringInChar(string,0,string->length);
	returnInt = evaluate(returnChar);
	
		
	free(string);
	
	return returnInt;
} //pass to jason
void test_stringSubstringInChar_should_crop_out_1(void) {
    int toCompare;
    Text *text = textNew("abc123");
    String *string  = stringNew(text);
    char *testing = stringSubstringInChar(string,3,1);

    toCompare = strcmp(testing,"1");
    TEST_ASSERT_EQUAL(0,toCompare);
}
void test_stringSubstringInChar_should_crop_out_Stone(void) {
    int toCompare;
    Text *text = textNew("StoneSir123");
    String *string  = stringNew(text);
    char *testing = stringSubstringInChar(string,0,5);

    toCompare = strcmp(testing,"Stone");
    TEST_ASSERT_EQUAL(0,toCompare);
}
int stringToInteger(String *str){
	int intValue;
	
	char *charStr = stringSubstringInChar(str, str->start, str->length);
	intValue = atoi(charStr);
	free(charStr);
	
	return intValue;
	
}
int stringToInteger(String *string){
	int starter,lengther,integerChar;
	starter = string->start;
	lengther = string->length;
	
	char *charStr = stringSubstringInChar(string,starter,lengther); 
	integerChar = atoi(charStr);
	
	free(charStr);
	
	return integerChar;
}
Text *stringSubstringInText(String *string,int start,int length){
	char *charStr = stringSubstringInChar(string,start,length);
	Text *text = textNew(charStr);
	free(charStr);
	return text;
}