/*  VT1500 Device Driver for Linux, Version 1.0.5
 *  Copyright (C) 1995  M. Gutschke
 *
 *  At the time of writing my e-mail address is:
 *	Internet: gutschk@uni-muenster.de
 *  My snail mail address is:
 *	Markus Gutschke
 *	Schlage 5a
 *	48268 Greven-Gimbte
 *	Germany
 *  If you like this software, I would appreciate if you sent me a postcard
 *  from your hometown. Under the terms of the GNU general public license
 *  you are free to include this program into (commercial) software
 *  distributions (e.g. putting it onto CD-ROM); nonetheless, I would really
 *  appreciate if you dropped me a short note (sending me a sample copy of
 *  your distribution would be even more appreciated!)
 *
 *  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, or
 *  (at your option) any later version.
 *
 *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>

#include "rc.h"
#include "tv.h"
#include "tvcontrol.h"

struct RCSettings RCSettings = {
  0,0,0,CHSTART,0,1,1,1,MAXBASS,MAXTREBLE,MAXVOLUME,DEFBRIGHTNESS,
  DEFSATURATION,DEFCONTRAST,DEFHUE,DEFRED,DEFGREEN,DEFBLUE };

static char *getFileName(void)
{
  static const char *rcname = ".tvrc";
  char *homeDir = getenv("HOME");

  if (homeDir) {
    char *ret = malloc(strlen(homeDir)+strlen(rcname)+2);
    if (ret)
      return(strcat(strcat(strcpy(ret,homeDir),"/"),rcname));
    else
      return(NULL); }
  else
    return(strdup(rcname));
}

void getSettings(void)
{
  extern FILE *rcin;
  extern      rcparse(void);
  char        *fileName;
  FILE        *fd;
  int         found = 0;

  if ((fileName = getFileName()) != NULL) {
    if ((fd = fopen(fileName,"r")) != NULL) {
      found = 1;
      rcin = fd;
      while (!feof(rcin))
	rcparse();
      fclose(fd); }
    free(fileName); }
  if (!found && 
      ((fd = fopen("/usr/local/etc/system.tvrc","r")) != NULL ||
       (fd = fopen("/usr/etc/system.tvrc","r")) != NULL ||
       (fd = fopen("/etc/system.tvrc","r")) != NULL)) {
    rcin = fd;
    while (!feof(rcin))
      rcparse();
    fclose(fd); }
  return;
}

static void writeStationSettings(FILE *fd)
{
  unsigned char bm1[16],bm2[16];
  int           index,frq,adj,prgNum,PALNTSC;
  const char    *name,*longName;
  int           duplicates = 0,isSettings = 0;

  memset(bm1,0,sizeof(bm1));
  memset(bm2,0,sizeof(bm2));
  for (index = -1; !channelInfo(&index,1,1,NULL,NULL,NULL,NULL,&prgNum,NULL); )
    if (prgNum >= 0) {
      isSettings = 1;
      if (bm1[prgNum/8] & (1 << (prgNum%8)))
	duplicates = 1;
      else
	bm1[prgNum/8] |= 1 << (prgNum%8); }
  if (!isSettings) {
    fprintf(fd,"#    no station settings\n");
    return; }
  if (duplicates)
    fprintf(fd,"# Duplicate station settings have automagically been moved"
	        " to a free slot!\n");
  for (index = -1; !channelInfo(&index,1,1,&name,&longName,&frq,&adj,
				&prgNum,&PALNTSC); )
    if (prgNum >= 0) {
      if (bm2[prgNum/8] & (1 << (prgNum%8))) {
	int i;
	for (i = 0; bm1[i] == 0xFF; i++);
	for (i *= 8; bm1[i/8] & (1 << (i%8)); i++);
	bm1[i/8] |= 1 << (i%8);
      prgNum = i; }
      else
	bm2[prgNum/8] |= 1 << (prgNum%8);
      fprintf(fd,"Station %2d: %3d%c%d.%dMHz %3s %-5s \"%s\"\n",
	      prgNum,frq/10,adj>=0?'+':'-',abs(adj)/10,abs(adj)%10,name,
	      PALNTSC?PALNTSC<0?"Radio":"PAL":"NTSC",longName); }
  return;
}

static int toPercentage(int val,int def,int maxval)
{
  if (val < def)
    return(((val-def)*100-(100/def))/def);
  else if (val == def)
    return(0);
  else
    return(((val-def)*100+100/(maxval-def))/(maxval-def));
}

static void writePreferences(FILE *fd)
{
  const char *longName;
  int channel,prgNum;

  if ((channel = getChannel()) >= 0) {
    channelInfo(&channel,1,0,NULL,&longName,NULL,NULL,&prgNum,NULL);
    fprintf(fd,"channel %d%s%s\n",prgNum,longName&&*longName ? " # " : "",
	    longName ? longName : ""); }
  fprintf(fd,"display %s\n"
	     "source %s\n"
	     "mode %s\n"
	     "mute %s\n"
	     "bass %d%%\n"
	     "treble %d%%\n"
	     "volume %d%%\n"
	     "brightness %+d%%\n"
	     "saturation %+d%%\n"
	     "contrast %+d%%\n"
	     "hue %+d%%\n"
	     "red %+d%%\n"
	     "green %+d%%\n"
	     "blue %+d%%\n",
	  isVisible() ? "Tuner" : "VGA",
	  getTVVCR() ? "TV" : "VCR",
	  getPALNTSC() ? "PAL" : "NTSC",
	  getMute() ? "ON" : "OFF",
	  toPercentage(getBass(),0,MAXBASS),
	  toPercentage(getTreble(),0,MAXTREBLE),
	  toPercentage(getVolume(),0,MAXVOLUME),
	  toPercentage(getBrightness(),DEFBRIGHTNESS,63),
	  toPercentage(getSaturation(),DEFSATURATION,63),
	  toPercentage(getContrast(),DEFCONTRAST,63),
	  toPercentage(getHue(),DEFHUE,255),
	  toPercentage(getRed(),DEFRED,63),
	  toPercentage(getGreen(),DEFGREEN,63),
	  toPercentage(getBlue(),DEFBLUE,63));
  return;
}

void saveSettings(void)
{
  char *fileName;
  FILE *fd;
  time_t curTime = time(NULL);

  if (RCSettings.readonly)
    return;
  if ((fileName = getFileName()) == NULL) {
    fprintf(stderr,"Could not write rc file: Out of memory!\n");
    return; }
  if ((fd = fopen(fileName,"w")) == NULL) {
    fprintf(stderr,"Could not write to %s: %s\n",fileName,strerror(errno));
    free(fileName);
    return; }
  free(fileName);
  fchown(fileno(fd),getuid(),-1);
  fprintf(fd,
	  "# VT1500 Device Driver for Linux, Version "VERSION"\n"
	  "# Copyright (C) "YEAR"  "AUTHOR"\n"
	  "# This configuration file has been generated on %s\n"
	  "#\n"
	  "# At the time of writing my e-mail address is:\n"
	  "#\tInternet: gutschk@uni-muenster.de\n"
	  "# My snail mail address is:\n"
	  "#\tMarkus Gutschke\n"
	  "#\tSchlage 5a\n"
	  "#\t48268 Greven-Gimbte\n"
	  "#\tGermany\n"
	  "# If you like this software, I would appreciate if you sent me a postcard\n"
	  "# from your hometown. Under the terms of the GNU general public license\n"
	  "# you are free to include this program into (commercial) software\n"
	  "# distributions (e.g. putting it onto CD-ROM); nonetheless, I would really\n"
	  "# appreciate if you dropped me a short note (sending me a sample copy of\n"
	  "# your distribution would be even more appreciated!)\n"
	  "#\n"
	  "# This program is free software; you can redistribute it and/or modify\n"
	  "# it under the terms of the GNU General Public License as published by\n"
	  "# the Free Software Foundation; either version 2 of the License, or\n"
	  "# (at your option) any later version.\n"
	  "#\n"
	  "# This program is distributed in the hope that it will be useful,\n"
	  "# but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
	  "# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
	  "# GNU General Public License for more details.\n"
	  "#\n"
	  "# You should have received a copy of the GNU General Public License\n"
	  "# along with this program; if not, write to the Free Software\n"
	  "# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n"
	  "\n"
	  "\n"
	  "\n"
	  "# Uncomment the following line if you want to make these\n"
	  "# settings permanent:\n"
	  "\n"
	  "# readonly\n"
	  "\n"
	  "# Uncomment the following line if you want to perform muting by\n"
	  "# switching to external input\n"
	  "\n"
	  "%sexternalmute\n"
	  "\n",
	  ctime(&curTime),RCSettings.externalMute ? "" : "# ");
  if (RCSettings.port > 0)
    fprintf(fd,
	    "# Select port address\n"
	    "\n"
	    "port 0x%X\n"
	    "\n",
	    RCSettings.port);
  else
    fprintf(fd,
	    "# Uncomment one of the following lines if you want to disable\n"
	    "# autoprobing for your card's port address\n"
	    "\n"
	    "# port 0x200\n"
	    "# port 0x300\n"
	    "\n");
  fprintf(fd,
	  "# Station settings\n"
	  "\n");
  writeStationSettings(fd);
  fprintf(fd,"\n"
	     "# User preferences\n"
	     "\n");
  writePreferences(fd);
  fprintf(fd,"\n"
             "# end of configuration file\n");
  fclose(fd);
  return;
}
