/* 
    channel for Bt848 frame grabber driver

    Copyright (C) 1996,97 Marcus Metzler (mocm@thp.uni-koeln.de)

    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.
*/

/*
 * channel.cc 
 */

#include "channel.h"
#include <string.h>

channel::channel(channel *h,int freq,char *n,int c,int b,int hu,int co,int no,int in,int num=-1)
{
  head=0;
  
  if (num <0 || num>cnt){
    while(h->next) h=h->next;
    h->next=this;
    cnt++;
    number=cnt;
    prev=h;
    next=NULL;
  } else {
    while((h->next)->number < num) h=h->next;
    next=h->next;
      h->next=this;
    next->prev=this;
    cnt++;
    number=num;
    h=this;
    while(h->next) {
      h=h->next;
	h->number++;
    }
  }
  name=new char[strlen(n)+1];
  strcpy(name,n);
  frequency=freq;
  color=c;
  brightness=b;
  hue=hu;
  contrast=co;
  norm=no;
  input=in;
}


channel::~channel(){
  channel *h=this;
  
  if (!head){
    (h->prev)->next=h->next;
    if (h->next) (h->next)->prev=h->prev;
    delete(name);
    while(h->next) {
      h=h->next;
      h->number--;
    }
    cnt--;
  } else {
    channel *n=this;
    
      while (n->next) {
	(n->next)->~channel();
      }
  }
}

ostream &operator<<(ostream &stream, channel &x){
  stream << "*" << endl;
  stream << "Channel: " << x.name << endl;
  stream << "Frequency: " << x.frequency << endl;
  stream << "CBHC: " << x.color << " "; 
  stream << x.brightness << " "; 
  stream << x.hue << " "; 
  stream << x.contrast << endl; 
  stream << "NI: " << x.norm << " "; 
  stream << x.input << endl; 
}

istream &operator>>(istream &stream, channel &x){
  char cdummy[50];
  stream >> cdummy >> cdummy;
  if (x.name) delete(x.name);
  x.name=new char[sizeof(cdummy)];
  strcpy(x.name,cdummy);
  stream.get(cdummy,sizeof(cdummy)); // get full channel name
  strcat(x.name,cdummy);

  stream >> cdummy >> x.frequency >> cdummy >> x.color >> x.brightness;
  stream >> x.hue >> x.contrast >> cdummy >> x.norm >> x.input; 
}

int interval::infreq(double freq)
{
  if (freq-fmin_<0 || fmax_-freq <=0 ) return 0;
  else  return 1;
}

int interval::inchan(int chan)
{
  if (chan-cmin_<0 || cmax_-chan <0 ) return 0;
  else  return 1;
}



ostream &operator<<(ostream &stream, interval &x){
  stream << x.fmin_ << " " << x.fmax_ << " " ;
  stream << x.cmin_ << " " << x.cmax_ << " " << x.chanstep_ << endl;
}

istream &operator>>(istream &stream, interval &x){
  stream >> x.fmin_ >> x.fmax_ ;
  stream >> x.cmin_ >> x.cmax_ >> x.chanstep_;
} 


country::country(int nb,char *nam)
{
  nb_=nb;
  name= new char[sizeof(nam)];
  strcpy(name,nam);
  iv= new interval[nb];
}
  
country::country(char *filename)
{
  ifstream fin(filename);
  fin >> *this;
}

void country::init(int nb,char *nam)
{
  if (name || iv){
    cerr << "Error: Can't initialize country" << endl;
    exit(1);
  }
  nb_=nb;
  name= new char[sizeof(nam)];
  strcpy(name,nam);
  iv= new interval[nb];
}
  
void country::init(char *filename)
{
  if (name || iv){
    cerr << "Error: Can't initialize country" << endl;
    exit(1);
  }
  ifstream fin(filename);
  fin >> *this;
}

double country::smax()
{
  double m;
  double max=0;
  for(int i=0;i<nb_;i++)
    if( (m=iv[i].chanstep_) > max) max=m;
  return max;
}

double country::fmax()
{
  double m;
  double max=0;
  for(int i=0;i<nb_;i++)
    if( (m=iv[i].fmax_) > max) max=m;
  return max;
}

double country::fmin()
{
  double m;
  double min=1000;

  for(int i=0;i<nb_;i++)
    if( (m=iv[i].fmin_) < min) min=m;

  return min;
}
  
int country::cmax()
{
  int m;
  int max=0;
  for(int i=0;i<nb_;i++)
    if( (m=iv[i].cmax_) > max) max=m;
  return max+1;
}

int country::cmin()
{
  int m;
  int min=1000;
  for(int i=0;i<nb_;i++)
    if( (m=iv[i].cmin_) < min) min=m;
  return min;
}

int country::freqtochan(int f)
{
  double freq=double(f)/16.0;

  for(int i=0;i<nb_;i++)
    if (iv[i].infreq(freq))
      return int((freq-iv[i].fmin_)/iv[i].chanstep_+.5)+iv[i].cmin_;

  return this->cmax();
}

int country::freqtofine(int f)
{
  int chan=freqtochan(f);
  int nf=cftofreq(chan,0);

  if (chan<this->cmax() && abs(f-nf)<=8*this->smax()) return (f-nf);
  else return 0;
}


int country::cftofreq(int chan, int fine)
{
  double freq;

  freq=0;
  for(int i=0;i<nb_;i++)
    if (iv[i].inchan(chan))
      freq= iv[i].fmin_+iv[i].chanstep_*(chan-iv[i].cmin_);

  if(!freq) return int(this->fmax())*16;
  return int(freq*16)+fine;
}


ostream &operator<<(ostream &stream, country &x){
  stream << "Country: " << x.name << endl;
  stream << x.nb_ << endl;
  for(int i=0;i<x.nb_;i++) stream << x.iv[i];
}

istream &operator>>(istream &stream, country &x){
  char cdummy[80];
  stream >> cdummy >> cdummy;
  x.name= new char[sizeof(cdummy)];
  strcpy(x.name,cdummy);
  stream >> x.nb_;
  if (x.iv) delete(x.iv);
  x.iv=new interval[x.nb_];
  for(int i=0;i<x.nb_;i++) stream >> x.iv[i];
}












