void wuclass_math_update(wuobject_t *wuobject) {
  int16_t input1;
  int16_t input2;
  int16_t input3;
  int16_t input4;
  int16_t op;
  int16_t output = 0;
  int16_t remainder = 0;

  wkpf_internal_read_property_int16(wuobject, WKPF_PROPERTY_MATH_OP_INPUT1, &input1);
  wkpf_internal_read_property_int16(wuobject, WKPF_PROPERTY_MATH_OP_INPUT2, &input2);
  wkpf_internal_read_property_int16(wuobject, WKPF_PROPERTY_MATH_OP_INPUT3, &input3);
  wkpf_internal_read_property_int16(wuobject, WKPF_PROPERTY_MATH_OP_INPUT4, &input4);
  wkpf_internal_read_property_int16(wuobject, WKPF_PROPERTY_MATH_OP_OPERATOR, &op);

  if(op==WKPF_ENUM_MATH_OP_OPERATOR_MAX) {
		if ( (input1>=input2) && (input1>=input3) && (input1>=input4))
			output=input1;
		else if ( (input2>=input1) && (input2>=input3) && (input2>=input4))
			output=input2;
		else if ( (input3>=input1) && (input3>=input2) && (input3>=input4))
			output=input3;
		else if ( (input4>=input1) && (input4>=input2) && (input4>=input3))
			output=input4;
		remainder=0;
  } else if(op==WKPF_ENUM_MATH_OP_OPERATOR_MIN) {
	  	if ( (input1<=input2) && (input1<=input3) && (input1<=input4))
			output=input1;
		else if ( (input2<=input1) && (input2<=input3) && (input2<=input4))
			output=input2;
		else if ( (input3<=input1) && (input3<=input2) && (input3<=input4))
			output=input3;
		else if ( (input4<=input1) && (input4<=input2) && (input4<=input3))
			output=input4;
		remainder=0;
  } else if(op==WKPF_ENUM_MATH_OP_OPERATOR_AVG) {
		output=(input1+input2+input3+input4)/4;
		remainder=0;
  } else if(op==WKPF_ENUM_MATH_OP_OPERATOR_ADD) {
		output=input1+input2+input3+input4;
		remainder=0;
  } else if(op==WKPF_ENUM_MATH_OP_OPERATOR_SUB) {	// input1-input2
		output=input1-input2;
		remainder=0;
  } else if(op==WKPF_ENUM_MATH_OP_OPERATOR_MULTIPLY) {
		output=input1*input2*input3*input4;
		remainder=0;
  } else if(op==WKPF_ENUM_MATH_OP_OPERATOR_DIVIDE) {	// input1/input2
		if(input2==0)
			DEBUG_LOG(DBG_WKPFUPDATE, "WKPFUPDATE(math): divide by 0 Error ");
	    output=input1/input2;
		remainder=input1%input2;
  }

    wkpf_internal_write_property_int16(wuobject, WKPF_PROPERTY_MATH_OP_OUTPUT, output);
	wkpf_internal_write_property_int16(wuobject, WKPF_PROPERTY_MATH_OP_REMAINDER, remainder);
    DEBUG_LOG(DBG_WKPFUPDATE, "WKPFUPDATE(math): Native math: input1 %x input2 %x input3 %x input4 %x operator %x-> output %x remainder %x\n", input1, input2, input3, input4, op, output, remainder);
}
void wuclass_light_sensor_update(wuobject_t *wuobject) {
	// Rotate through values 0 to 255 in steps of 10
	int16_t value;
	wkpf_internal_read_property_int16(wuobject, WKPF_PROPERTY_LIGHT_ACTUATOR_ON_OFF, &value);
	value += 10;
	value %= 256;
	DEBUG_LOG(DBG_WKPFUPDATE, "WKPFUPDATE(Light sensor): 'Sensed' dummy value: %d\n", value);
	wkpf_internal_write_property_int16(wuobject, WKPF_PROPERTY_LIGHT_SENSOR_CURRENT_VALUE, value);
}
void wuclass_temperature_humidity_sensor_update(wuobject_t *wuobject) {
    sbi(TCCR0B, CS01);
    sbi(TCCR0B, CS00);	
    sbi(TIMSK0, TOIE0);    
    SHT1x(5,6);
    
    int temperature, temperatureRaw, humidityRaw, humidity;
    temperatureRaw=readTemperatureRaw();
    temperatureRaw=temperatureRaw-4000;
    temperature=temperatureRaw/100;
    
    humidityRaw=readHumidity();
    humidity=(temperature*(100000+800*humidityRaw) + (405000+28*humidityRaw)*humidityRaw - 4*10000000)/10000000 - 11;
    
    DEBUG_LOG(DBG_WKPFUPDATE, "WKPFUPDATE(TemperatureHumiditySensor): Sensed temperature value: %d.%dC\n", temperature, temperatureRaw%100);
    DEBUG_LOG(DBG_WKPFUPDATE, "WKPFUPDATE(TemperatureHumiditySensor): Sensed humidity value: %d %% \n", humidity);
    wkpf_internal_write_property_int16(wuobject, WKPF_PROPERTY_TEMPERATURE_HUMIDITY_SENSOR_CURRENT_VALUE_TEMPERATURE, temperature);
    wkpf_internal_write_property_int16(wuobject, WKPF_PROPERTY_TEMPERATURE_HUMIDITY_SENSOR_CURRENT_VALUE_HUMIDITY, humidity);
}
void javax_wukong_wkpf_WKPF_void_setPropertyShort_javax_wukong_wkpf_VirtualWuObject_byte_short() {
	int16_t value = (int16_t)dj_exec_stackPopShort();
	uint8_t property_number = (uint8_t)dj_exec_stackPopShort();
	dj_object *java_instance_reference = REF_TO_VOIDP(dj_exec_stackPopRef());
	wuobject_t *wuobject;
	wkpf_error_code = wkpf_get_wuobject_by_java_instance_reference(java_instance_reference, &wuobject);
	if (wkpf_error_code == WKPF_OK) {
		wkpf_error_code = wkpf_internal_write_property_int16(wuobject, property_number, value);
	}
}
void wuclass_ir_sensor_update(wuobject_t *wuobject) {

 //enable ADC and set prescaler value

 ADCSRA = _BV(ADEN) | _BV(ADPS2);

 //ADCSRA = _BV(ADEN) | (6 & 7); // set prescaler value

 //set ADC channel, reference value and left shift

 uint8_t channel = 0;

 //ADMUX = (channel & 0x0f) | 0xc0 | _BV(ADLAR);

 ADMUX = (channel & 0x0f) | 0xc0;

 //ADMUX = (ADMUX & 0xc0) | _BV(ADLAR) | (channel & 0x0f);

 //ADCSRB |= (channel & 0x20)>>2;

 //do conversion

 ADCSRA |= _BV(ADSC);

 //wait for conversion complete

 while(!(ADCSRA & _BV(ADIF)));

 //clear ADIF

 ADCSRA &= ~(_BV(ADIF));

 //uint16_t cm = 0;

 uint16_t sensorValue = ADCL;

 sensorValue += (ADCH << 8);

 sensorValue /= 2;

 //float volts = sensorValue * 0.0048828125;

 //uint16_t distance = 65 * pow(volts, -1.10);

 float volts = 10650.08 * pow(sensorValue, -0.935);

 uint16_t distance = (uint16_t)(volts - 10);

 //cm = (uint16_t)pow(sensorValue, 1);

 DEBUG_LOG(DBG_WKPFUPDATE, "WKPFUPDATE(irSensor): Sensed ir value: %d, ADC: %d\n",distance, sensorValue);

 wkpf_internal_write_property_int16(wuobject, WKPF_PROPERTY_IR_SENSOR_SIGNAL, distance);

}
void wuclass_light_sensor_update(wuobject_t *wuobject) {
  // Pieced together from IntelDemoLightSensorV1.java, Adc.java and native_avr.c

  // Adc.setPrescaler(Adc.DIV64);
  ADCSRA = _BV(ADEN) | (6 & 7);  // set prescaler value

  // Adc.setReference(Adc.INTERNAL);
  ADMUX = (3 << 6) & 0xc0;              // set reference value

  // light_sensor_reading = Adc.getByte(Adc.CHANNEL0);
  // ADLAR = 1
  uint8_t channel  = 0; // NOTE: Adc.CHANNEL0 means a value of 0 for the channel variable, but other ADC channels don't map 1-1. For instance channel 15 is selected by setting the channel variable to 39. See Adc.Java for a list.
  ADMUX = (ADMUX & 0xc0) | _BV(ADLAR) | (channel & 0x0f);
  ADCSRB |= (channel & 0x20)>>2;

  // do conversion
  ADCSRA |= _BV(ADSC);                  // Start conversion
  while(!(ADCSRA & _BV(ADIF)));         // wait for conversion complete
  ADCSRA |= _BV(ADIF);                  // clear ADCIF
  DEBUG_LOG(DBG_WKCOMM, "WKPFUPDATE(LightSensor): Sensed light value: %d\n", ADCH);
  wkpf_internal_write_property_int16(wuobject, WKPF_PROPERTY_LIGHT_SENSOR_CURRENT_VALUE, ADCH);
}
void wuclass_generic_update(wuobject_t *wuobject) {
    DEBUG_LOG(DBG_WKPFUPDATE, "WKPFUPDATE(Generic): Update called for generic wuclass\n");
    wkpf_internal_write_property_int16(wuobject, WKPF_PROPERTY_GENERIC_DUMMY, 42);
}