/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
 *
 * Copyright (c) 2018 Vikrant More
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <math.h>

#include "common.h"
#include "ble_mesh.h"
#include "device_composition.h"

static s32_t ceiling(float num)
{
	s32_t inum;

	inum = (s32_t) num;
	if (num == (float) inum) {
		return inum;
	}

	return inum + 1;
}

static bool constrain_light_actual_state(u16_t var)
{
	bool is_value_within_range;

	is_value_within_range = false;

	if (var > 0 &&
	    var < light_lightness_srv_user_data.light_range_min) {
		var = light_lightness_srv_user_data.light_range_min;
	} else if (var > light_lightness_srv_user_data.light_range_max) {
		var = light_lightness_srv_user_data.light_range_max;
	} else {
		is_value_within_range = true;
	}

	light_lightness_srv_user_data.actual = var;

	return is_value_within_range;
}

static void update_gen_onoff_state(void)
{
	if (light_lightness_srv_user_data.actual == 0) {
		gen_onoff_srv_root_user_data.onoff = STATE_OFF;
	} else {
		gen_onoff_srv_root_user_data.onoff = STATE_ON;
	}
}

void state_binding(u8_t lightness, u8_t temperature)
{
	bool is_value_within_range;
	u16_t tmp16;
	float tmp;

	switch (temperature) {
	case ONOFF_TEMP:/* Temp. update as per Light CTL temp. default state */
	case CTL_TEMP:	/* Temp. update as per Light CTL temp. state */
		/* Mesh Model Specification 6.1.3.1.1 2nd formula start */
		tmp = (light_ctl_srv_user_data.temp -
		       light_ctl_srv_user_data.temp_range_min) * 65535;
		tmp = tmp / (light_ctl_srv_user_data.temp_range_max -
			     light_ctl_srv_user_data.temp_range_min);
		gen_level_srv_s0_user_data.level = tmp - 32768;
		/* 6.1.3.1.1 2nd formula end */
		break;
	case LEVEL_TEMP:/* Temp. update as per Generic Level (s0) state */
		/* Mesh Model Specification 6.1.3.1.1 1st formula start */
		tmp = (float) (light_ctl_srv_user_data.temp_range_max -
			       light_ctl_srv_user_data.temp_range_min) / 65535;
		tmp = (gen_level_srv_s0_user_data.level + 32768) * tmp;
		light_ctl_srv_user_data.temp =
			light_ctl_srv_user_data.temp_range_min + tmp;
		/* 6.1.3.1.1 1st formula end */
		break;
	default:
		break;
	}

	tmp16 = 0;

	switch (lightness) {
	case ONPOWERUP: /* Lightness update as per Generic OnPowerUp state */
		if (gen_onoff_srv_root_user_data.onoff == STATE_OFF) {
			light_lightness_srv_user_data.actual = 0;
			light_lightness_srv_user_data.linear = 0;
			gen_level_srv_root_user_data.level = -32768;
			light_ctl_srv_user_data.lightness = 0;
			return;
		} else if (gen_onoff_srv_root_user_data.onoff == STATE_ON) {
			light_lightness_srv_user_data.actual =
				light_lightness_srv_user_data.last;
		}

		break;
	case ONOFF: /* Lightness update as per Generic OnOff (root) state */
		if (gen_onoff_srv_root_user_data.onoff == STATE_OFF) {
			light_lightness_srv_user_data.actual = 0;
			light_lightness_srv_user_data.linear = 0;
			gen_level_srv_root_user_data.level = -32768;
			light_ctl_srv_user_data.lightness = 0;
			return;
		} else if (gen_onoff_srv_root_user_data.onoff == STATE_ON) {
			if (light_lightness_srv_user_data.def == 0) {
				light_lightness_srv_user_data.actual =
					light_lightness_srv_user_data.last;
			} else {
				light_lightness_srv_user_data.actual =
					light_lightness_srv_user_data.def;
			}
		}

		break;
	case LEVEL: /* Lightness update as per Generic Level (root) state */
		tmp16 = gen_level_srv_root_user_data.level + 32768;
		constrain_light_actual_state(tmp16);
		update_gen_onoff_state();
		break;
	case DELTA_LEVEL: /* Lightness update as per Gen. Level (root) state */
		/* This is as per Mesh Model Specification 3.3.2.2.3 */
		tmp16 = gen_level_srv_root_user_data.level + 32768;
		if (tmp16 > 0 &&
		    tmp16 < light_lightness_srv_user_data.light_range_min) {
			if (gen_level_srv_root_user_data.last_delta < 0) {
				tmp16 = 0;
			} else {
				tmp16 =
				light_lightness_srv_user_data.light_range_min;
			}
		} else if (tmp16 >
			   light_lightness_srv_user_data.light_range_max) {
			tmp16 =
			light_lightness_srv_user_data.light_range_max;
		}

		light_lightness_srv_user_data.actual = tmp16;

		update_gen_onoff_state();
		break;
	case ACTUAL: /* Lightness update as per Light Lightness Actual state */
		update_gen_onoff_state();
		break;
	case LINEAR: /* Lightness update as per Light Lightness Linear state */
		tmp16 = (u16_t) 65535 *
			sqrt(((float) light_lightness_srv_user_data.linear /
			      65535));

		is_value_within_range = constrain_light_actual_state(tmp16);
		update_gen_onoff_state();

		if (is_value_within_range) {
			goto ignore_linear_update_others;
		}

		break;
	case CTL: /* Lightness update as per Light CTL Lightness state */
		constrain_light_actual_state(light_ctl_srv_user_data.lightness);
		update_gen_onoff_state();
		break;
	default:
		return;
	}

	tmp = ((float) light_lightness_srv_user_data.actual / 65535);
	light_lightness_srv_user_data.linear = ceiling(65535 * tmp * tmp);

ignore_linear_update_others:
	if (light_lightness_srv_user_data.actual != 0) {
		light_lightness_srv_user_data.last =
			light_lightness_srv_user_data.actual;
	}

	gen_level_srv_root_user_data.level =
		light_lightness_srv_user_data.actual - 32768;

	light_ctl_srv_user_data.lightness =
		light_lightness_srv_user_data.actual;
}
