void lavaFunction(int, int (*)(int, int));
int (*lavaFunction2)(int, int);
int lavaMulti(int, int);
void lavaSwap(int *, int *);
void modifyPointer(int **, int *);


struct LavaType3 {
	char foad;
	char bofh;
}; 

typedef struct LavaType5StructTag {
	char foad1;
	char bofh1;
} LavaType5;

typedef int LAVATYPE2;
typedef struct LavaType3 LAVATYPE4;

typedef struct {
	int bubbles;
	char colorCode;
} LAVATYPE;


int main () {

struct LavaType3 testStruct1;

LAVATYPE2 bdPresent_int;

LAVATYPE4 newpresent2;
LavaType5 newpresent1;

/* test swap function */
int temp1 = 0, temp2 = 1;

printf("before: %d | %d | %x | %x\n", temp1, temp2, &temp1, &temp2);
lavaSwap(&temp1, &temp2);
printf("after:  %d | %d | %x | %x\n", temp1, temp2, &temp1, &temp2);

/* something else */
int temp3 = 4, temp4 = 4;
lavaFunction2 = lavaMulti;

printf("test multi: %d\n", lavaMulti(temp3, temp4));
printf("test multi: %d\n", lavaFunction2(temp3, temp4));

lavaFunction(100, lavaMulti);

/* example pointer to pointer */
int modOrig = 100, modOrigTo=201, *modPtr;

modPtr = &modOrig;

printf("\nAddr of ints: %x | %x\n", &modOrig, &modOrigTo);
printf("DEBUG: address: %x | value: %x | target value: %d\n", &modPtr, modPtr, *modPtr);
modifyPointer(&modPtr, &modOrigTo);
printf("DEBUG: address: %x | value: %x | target value: %d\n", &modPtr, modPtr, *modPtr);

return 0;
}



void modifyPointer(int **localModPtr, int *modNew3Ptr){
 
int modNew2 = 102, *modNew2Ptr;		
modNew2Ptr = &modNew2;

printf("DEBUG locals: address of int: %x | address of ptr to int: %x | target of ptr: %x, value of target: %d\n", &modNew2, &modNew2Ptr, modNew2Ptr, *modNew2Ptr);

printf("DEBUG: local address: %x | local value: %x | target of target: %x |  target: %d\n", &localModPtr, localModPtr, *localModPtr, **localModPtr);
*localModPtr = modNew3Ptr;
/*
 *localModPtr = modNew2Ptr;
 *localModPtr = &modNew2; 
*/
}


void lavaFunction(int local1, int (*lavaFunction3)(int, int)) {

int temp3 = 4, temp4 = 4;

printf("test multi: %d\n", lavaFunction3(temp3, temp4));
printf("test multi: %d\n", (*lavaFunction3)(temp3, temp4));

} 

int lavaMulti(int origA, int origB) {

return origA * origB;

}

void lavaSwap(int *origA, int *origB) {

printf("local : %x | %x\n", &origA, &origB);
printf("passed: %x | %x\n", origA, origB);
	
int buf;

buf = *origA;
*origA = *origB;
*origB = buf;

}

