/*
 *
 *
 *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include "pvrusb2-ctrl.h"
#include "pvrusb2-hdw-internal.h"
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mutex.h>


static int pvr2_ctrl_range_check(struct pvr2_ctrl *cptr,int val)
{
	if (cptr->info->check_value) {
		if (!cptr->info->check_value(cptr,val)) return -ERANGE;
	} else if (cptr->info->type == pvr2_ctl_enum) {
		if (val < 0) return -ERANGE;
		if (val >= cptr->info->def.type_enum.count) return -ERANGE;
	} else {
		int lim;
		lim = cptr->info->def.type_int.min_value;
		if (cptr->info->get_min_value) {
			cptr->info->get_min_value(cptr,&lim);
		}
		if (val < lim) return -ERANGE;
		lim = cptr->info->def.type_int.max_value;
		if (cptr->info->get_max_value) {
			cptr->info->get_max_value(cptr,&lim);
		}
		if (val > lim) return -ERANGE;
	}
	return 0;
}


/* Set the given control. */
int pvr2_ctrl_set_value(struct pvr2_ctrl *cptr,int val)
{
	return pvr2_ctrl_set_mask_value(cptr,~0,val);
}


/* Set/clear specific bits of the given control. */
int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val)
{
	int ret = 0;
	if (!cptr) return -EINVAL;
	LOCK_TAKE(cptr->hdw->big_lock); do {
		if (cptr->info->set_value) {
			if (cptr->info->type == pvr2_ctl_bitmask) {
				mask &= cptr->info->def.type_bitmask.valid_bits;
			} else if ((cptr->info->type == pvr2_ctl_int)||
				   (cptr->info->type == pvr2_ctl_enum)) {
				ret = pvr2_ctrl_range_check(cptr,val);
				if (ret < 0) break;
			} else if (cptr->info->type != pvr2_ctl_bool) {
				break;
			}
			ret = cptr->info->set_value(cptr,mask,val);
		} else {
			ret = -EPERM;
		}
	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
	return ret;
}


/* Get the current value of the given control. */
int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr,int *valptr)
{
	int ret = 0;
	if (!cptr) return -EINVAL;
	LOCK_TAKE(cptr->hdw->big_lock); do {
		ret = cptr->info->get_value(cptr,valptr);
	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
	return ret;
}


/* Retrieve control's type */
enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *cptr)
{
	if (!cptr) return pvr2_ctl_int;
	return cptr->info->type;
}


/* Retrieve control's maximum value (int type) */
int pvr2_ctrl_get_max(struct pvr2_ctrl *cptr)
{
	int ret = 0;
	if (!cptr) return 0;
	LOCK_TAKE(cptr->hdw->big_lock); do {
		if (cptr->info->get_max_value) {
			cptr->info->get_max_value(cptr,&ret);
		} else if (cptr->info->type == pvr2_ctl_int) {
			ret = cptr->info->def.type_int.max_value;
		}
	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
	return ret;
}


/* Retrieve control's minimum value (int type) */
int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr)
{
	int ret = 0;
	if (!cptr) return 0;
	LOCK_TAKE(cptr->hdw->big_lock); do {
		if (cptr->info->get_min_value) {
			cptr->info->get_min_value(cptr,&ret);
		} else if (cptr->info->type == pvr2_ctl_int) {
			ret = cptr->info->def.type_int.min_value;
		}
	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
	return ret;
}


/* Retrieve control's default value (any type) */
int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr)
{
	int ret = 0;
	if (!cptr) return 0;
	LOCK_TAKE(cptr->hdw->big_lock); do {
		if (cptr->info->type == pvr2_ctl_int) {
			ret = cptr->info->default_value;
		}
	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
	return ret;
}


/* Retrieve control's enumeration count (enum only) */
int pvr2_ctrl_get_cnt(struct pvr2_ctrl *cptr)
{
	int ret = 0;
	if (!cptr) return 0;
	LOCK_TAKE(cptr->hdw->big_lock); do {
		if (cptr->info->type == pvr2_ctl_enum) {
			ret = cptr->info->def.type_enum.count;
		}
	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
	return ret;
}


/* Retrieve control's valid mask bits (bit mask only) */
int pvr2_ctrl_get_mask(struct pvr2_ctrl *cptr)
{
	int ret = 0;
	if (!cptr) return 0;
	LOCK_TAKE(cptr->hdw->big_lock); do {
		if (cptr->info->type == pvr2_ctl_bitmask) {
			ret = cptr->info->def.type_bitmask.valid_bits;
		}
	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
	return ret;
}


/* Retrieve the control's name */
const char *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr)
{
	if (!cptr) return NULL;
	return cptr->info->name;
}


/* Retrieve the control's desc */
const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *cptr)
{
	if (!cptr) return NULL;
	return cptr->info->desc;
}


/* Retrieve a control enumeration or bit mask value */
int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val,
			  char *bptr,unsigned int bmax,
			  unsigned int *blen)
{
	int ret = -EINVAL;
	if (!cptr) return 0;
	*blen = 0;
	LOCK_TAKE(cptr->hdw->big_lock); do {
		if (cptr->info->type == pvr2_ctl_enum) {
			const char **names;
			names = cptr->info->def.type_enum.value_names;
			if (pvr2_ctrl_range_check(cptr,val) == 0) {
				if (names[val]) {
					*blen = scnprintf(
						bptr,bmax,"%s",
						names[val]);
				} else {
					*blen = 0;
				}
				ret = 0;
			}
		} else if (cptr->info->type == pvr2_ctl_bitmask) {
			const char **names;
			unsigned int idx;
			int msk;
			names = cptr->info->def.type_bitmask.bit_names;
			val &= cptr->info->def.type_bitmask.valid_bits;
			for (idx = 0, msk = 1; val; idx++, msk <<= 1) {
				if (val & msk) {
					*blen = scnprintf(bptr,bmax,"%s",
							  names[idx]);
					ret = 0;
					break;
				}
			}
		}
	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
	return ret;
}


/* Return V4L ID for this control or zero if none */
int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *cptr)
{
	if (!cptr) return 0;
	return cptr->info->v4l_id;
}


unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *cptr)
{
	unsigned int flags = 0;

	if (cptr->info->get_v4lflags) {
		flags = cptr->info->get_v4lflags(cptr);
	}

	if (cptr->info->set_value) {
		flags &= ~V4L2_CTRL_FLAG_READ_ONLY;
	} else {
		flags |= V4L2_CTRL_FLAG_READ_ONLY;
	}

	return flags;
}


/* Return true if control is writable */
int pvr2_ctrl_is_writable(struct pvr2_ctrl *cptr)
{
	if (!cptr) return 0;
	return cptr->info->set_value != NULL;
}


/* Return true if control has custom symbolic representation */
int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *cptr)
{
	if (!cptr) return 0;
	if (!cptr->info->val_to_sym) return 0;
	if (!cptr->info->sym_to_val) return 0;
	return !0;
}


/* Convert a given mask/val to a custom symbolic value */
int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *cptr,
				  int mask,int val,
				  char *buf,unsigned int maxlen,
				  unsigned int *len)
{
	if (!cptr) return -EINVAL;
	if (!cptr->info->val_to_sym) return -EINVAL;
	return cptr->info->val_to_sym(cptr,mask,val,buf,maxlen,len);
}


/* Convert a symbolic value to a mask/value pair */
int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *cptr,
				  const char *buf,unsigned int len,
				  int *maskptr,int *valptr)
{
	if (!cptr) return -EINVAL;
	if (!cptr->info->sym_to_val) return -EINVAL;
	return cptr->info->sym_to_val(cptr,buf,len,maskptr,valptr);
}


static unsigned int gen_bitmask_string(int msk,int val,int msk_only,
				       const char **names,
				       char *ptr,unsigned int len)
{
	unsigned int idx;
	long sm,um;
	int spcFl;
	unsigned int uc,cnt;
	const char *idStr;

	spcFl = 0;
	uc = 0;
	um = 0;
	for (idx = 0, sm = 1; msk; idx++, sm <<= 1) {
		if (sm & msk) {
			msk &= ~sm;
			idStr = names[idx];
			if (idStr) {
				cnt = scnprintf(ptr,len,"%s%s%s",
						(spcFl ? " " : ""),
						(msk_only ? "" :
						 ((val & sm) ? "+" : "-")),
						idStr);
				ptr += cnt; len -= cnt; uc += cnt;
				spcFl = !0;
			} else {
				um |= sm;
			}
		}
	}
	if (um) {
		if (msk_only) {
			cnt = scnprintf(ptr,len,"%s0x%lx",
					(spcFl ? " " : ""),
					um);
			ptr += cnt; len -= cnt; uc += cnt;
			spcFl = !0;
		} else if (um & val) {
			cnt = scnprintf(ptr,len,"%s+0x%lx",
					(spcFl ? " " : ""),
					um & val);
			ptr += cnt; len -= cnt; uc += cnt;
			spcFl = !0;
		} else if (um & ~val) {
			cnt = scnprintf(ptr,len,"%s+0x%lx",
					(spcFl ? " " : ""),
					um & ~val);
			ptr += cnt; len -= cnt; uc += cnt;
			spcFl = !0;
		}
	}
	return uc;
}


static const char *boolNames[] = {
	"false",
	"true",
	"no",
	"yes",
};


static int parse_token(const char *ptr,unsigned int len,
		       int *valptr,
		       const char **names,unsigned int namecnt)
{
	char buf[33];
	unsigned int slen;
	unsigned int idx;
	int negfl;
	char *p2;
	*valptr = 0;
	if (!names) namecnt = 0;
	for (idx = 0; idx < namecnt; idx++) {
		if (!names[idx]) continue;
		slen = strlen(names[idx]);
		if (slen != len) continue;
		if (memcmp(names[idx],ptr,slen)) continue;
		*valptr = idx;
		return 0;
	}
	negfl = 0;
	if ((*ptr == '-') || (*ptr == '+')) {
		negfl = (*ptr == '-');
		ptr++; len--;
	}
	if (len >= sizeof(buf)) return -EINVAL;
	memcpy(buf,ptr,len);
	buf[len] = 0;
	*valptr = simple_strtol(buf,&p2,0);
	if (negfl) *valptr = -(*valptr);
	if (*p2) return -EINVAL;
	return 1;
}


static int parse_mtoken(const char *ptr,unsigned int len,
			int *valptr,
			const char **names,int valid_bits)
{
	char buf[33];
	unsigned int slen;
	unsigned int idx;
	char *p2;
	int msk;
	*valptr = 0;
	for (idx = 0, msk = 1; valid_bits; idx++, msk <<= 1) {
		if (!(msk & valid_bits)) continue;
		valid_bits &= ~msk;
		if (!names[idx]) continue;
		slen = strlen(names[idx]);
		if (slen != len) continue;
		if (memcmp(names[idx],ptr,slen)) continue;
		*valptr = msk;
		return 0;
	}
	if (len >= sizeof(buf)) return -EINVAL;
	memcpy(buf,ptr,len);
	buf[len] = 0;
	*valptr = simple_strtol(buf,&p2,0);
	if (*p2) return -EINVAL;
	return 0;
}


static int parse_tlist(const char *ptr,unsigned int len,
		       int *maskptr,int *valptr,
		       const char **names,int valid_bits)
{
	unsigned int cnt;
	int mask,val,kv,mode,ret;
	mask = 0;
	val = 0;
	ret = 0;
	while (len) {
		cnt = 0;
		while ((cnt < len) &&
		       ((ptr[cnt] <= 32) ||
			(ptr[cnt] >= 127))) cnt++;
		ptr += cnt;
		len -= cnt;
		mode = 0;
		if ((*ptr == '-') || (*ptr == '+')) {
			mode = (*ptr == '-') ? -1 : 1;
			ptr++;
			len--;
		}
		cnt = 0;
		while (cnt < len) {
			if (ptr[cnt] <= 32) break;
			if (ptr[cnt] >= 127) break;
			cnt++;
		}
		if (!cnt) break;
		if (parse_mtoken(ptr,cnt,&kv,names,valid_bits)) {
			ret = -EINVAL;
			break;
		}
		ptr += cnt;
		len -= cnt;
		switch (mode) {
		case 0:
			mask = valid_bits;
			val |= kv;
			break;
		case -1:
			mask |= kv;
			val &= ~kv;
			break;
		case 1:
			mask |= kv;
			val |= kv;
			break;
		default:
			break;
		}
	}
	*maskptr = mask;
	*valptr = val;
	return ret;
}


/* Convert a symbolic value to a mask/value pair */
int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
			   const char *ptr,unsigned int len,
			   int *maskptr,int *valptr)
{
	int ret = -EINVAL;
	unsigned int cnt;

	*maskptr = 0;
	*valptr = 0;

	cnt = 0;
	while ((cnt < len) && ((ptr[cnt] <= 32) || (ptr[cnt] >= 127))) cnt++;
	len -= cnt; ptr += cnt;
	cnt = 0;
	while ((cnt < len) && ((ptr[len-(cnt+1)] <= 32) ||
			       (ptr[len-(cnt+1)] >= 127))) cnt++;
	len -= cnt;

	if (!len) return -EINVAL;

	LOCK_TAKE(cptr->hdw->big_lock); do {
		if (cptr->info->type == pvr2_ctl_int) {
			ret = parse_token(ptr,len,valptr,NULL,0);
			if (ret >= 0) {
				ret = pvr2_ctrl_range_check(cptr,*valptr);
			}
			if (maskptr) *maskptr = ~0;
		} else if (cptr->info->type == pvr2_ctl_bool) {
			ret = parse_token(ptr,len,valptr,boolNames,
					  ARRAY_SIZE(boolNames));
			if (ret == 1) {
				*valptr = *valptr ? !0 : 0;
			} else if (ret == 0) {
				*valptr = (*valptr & 1) ? !0 : 0;
			}
			if (maskptr) *maskptr = 1;
		} else if (cptr->info->type == pvr2_ctl_enum) {
			ret = parse_token(
				ptr,len,valptr,
				cptr->info->def.type_enum.value_names,
				cptr->info->def.type_enum.count);
			if (ret >= 0) {
				ret = pvr2_ctrl_range_check(cptr,*valptr);
			}
			if (maskptr) *maskptr = ~0;
		} else if (cptr->info->type == pvr2_ctl_bitmask) {
			ret = parse_tlist(
				ptr,len,maskptr,valptr,
				cptr->info->def.type_bitmask.bit_names,
				cptr->info->def.type_bitmask.valid_bits);
		}
	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
	return ret;
}


/* Convert a given mask/val to a symbolic value */
int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr,
				    int mask,int val,
				    char *buf,unsigned int maxlen,
				    unsigned int *len)
{
	int ret = -EINVAL;

	*len = 0;
	if (cptr->info->type == pvr2_ctl_int) {
		*len = scnprintf(buf,maxlen,"%d",val);
		ret = 0;
	} else if (cptr->info->type == pvr2_ctl_bool) {
		*len = scnprintf(buf,maxlen,"%s",val ? "true" : "false");
		ret = 0;
	} else if (cptr->info->type == pvr2_ctl_enum) {
		const char **names;
		names = cptr->info->def.type_enum.value_names;
		if ((val >= 0) &&
		    (val < cptr->info->def.type_enum.count)) {
			if (names[val]) {
				*len = scnprintf(
					buf,maxlen,"%s",
					names[val]);
			} else {
				*len = 0;
			}
			ret = 0;
		}
	} else if (cptr->info->type == pvr2_ctl_bitmask) {
		*len = gen_bitmask_string(
			val & mask & cptr->info->def.type_bitmask.valid_bits,
			~0,!0,
			cptr->info->def.type_bitmask.bit_names,
			buf,maxlen);
	}
	return ret;
}


/* Convert a given mask/val to a symbolic value */
int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *cptr,
			   int mask,int val,
			   char *buf,unsigned int maxlen,
			   unsigned int *len)
{
	int ret;
	LOCK_TAKE(cptr->hdw->big_lock); do {
		ret = pvr2_ctrl_value_to_sym_internal(cptr,mask,val,
						      buf,maxlen,len);
	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
	return ret;
}


/*
  Stuff for Emacs to see, in order to encourage consistent editing style:
  *** Local Variables: ***
  *** mode: c ***
  *** fill-column: 75 ***
  *** tab-width: 8 ***
  *** c-basic-offset: 8 ***
  *** End: ***
  */
