/* 
   CAM - Cpu's Audio Mixer for Linux 
 
   AUTHOR: Jan 'TWP' VANDENBERGHE (jvdbergh@uia.ua.ac.be) 
 
*/ 
 
/* 
     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 <fcntl.h> 
#include <unistd.h> 
#include <sys/ioctl.h> 
#include <sys/soundcard.h> 
#include <ncurses.h> 
 
#include "screens.h" 
#include "sounds.h" 
 
extern int devmask , recmask , recsrc , stereodevs , mixer_fd; 
extern char *devname[DEV_COUNT]; 
extern int  dev_vol[DEV_COUNT][2] , dev_nr  ; 
 

/* gives status */ 
void status(char *status_line) 
{ 
   attrset(A_NORMAL); 
   mvaddstr(23,35,"              "); 
   attrset(COLOR_PAIR(COLOR_STATUS) | A_BOLD ); 
   mvaddstr(23,35,status_line); 
   attrset(A_NORMAL | A_ALTCHARSET); 
} 
 
/* Sends a message to the user */ 
void message(char *message_line) 
{ 
   
   attrset(A_NORMAL); 
   move(23,50); 
   clrtoeol(); 
   attrset( COLOR_PAIR(COLOR_MSG) ); 
   mvaddstr(23,50,message_line); 
   attrset(A_NORMAL | A_ALTCHARSET); 
} 
 
/* restores screen */ 
void stop(void) 
{ 
   attrset(A_NORMAL); 
   clear(); 
   echo(); 
   refresh(); 
   endwin(); 
   close(mixer_fd); 
 } 
 
/* gets n bits from x starting from position p */
int getbits(int x, int p, int n) 
{ 
  return ( x >> ( p+1-n) ) & ~(~0 << n ); 
} 
 
 
/* 
   Draws a handle
   1 : handle + left     2 : left + handle + right 
   3 : handle + right    4 : handle 
   5 : slide
 */ 
void Draw_handle(int level,int act, int left) 
{ 
   if ( (level == 3 ) || ( level == 2 ))
   { 
     attrset(A_NORMAL | A_ALTCHARSET ); 
     mvaddch(Y_POS+left,X_POS+dev_vol[dev_nr][left]-1,205); 
   } 
   if ( level != 5) 
   { 
      
      attrset(( act  ? ACT_HANDLE : NACT_HANDLE)); 
      mvaddch(Y_POS+left,X_POS+dev_vol[dev_nr][left],178); 
   } 
   if ( (level == 1) || (level == 2) ) 
   { 
     attrset(A_NORMAL | A_ALTCHARSET); 
     mvaddch(Y_POS+left,X_POS+dev_vol[dev_nr][left]+1,205); 
 
   } 
   if ( level  == 5 ) 
   { 
     attrset(A_NORMAL | A_ALTCHARSET); 
     mvaddch(Y_POS+left,X_POS+dev_vol[dev_nr][left],205); 
   } 
} 
 
/* Draws the slides */ 
void Draw_slide(void) 
{ 
   int i; 
   attrset( ( DEV_EXIST ? COLOR_PAIR(COLOR_ACT_SLIDE)  : COLOR_PAIR(COLOR_NACT_SLIDE) | A_BOLD ) ); 
   mvaddstr(Y_POS,X_POS - 12,devname[dev_nr]); 
   mvaddstr(Y_POS,X_POS - 6,"Left"); 
   mvaddstr(Y_POS+1,X_POS - 6,"Right"); 
   for (i=20; i >= 0 ; i--) 
   { 
       if ( i < 7 )  
          attrset(COLOR_PAIR( COLOR_VOL1) | A_ALTCHARSET);      
       else if ( i < 15 ) 
               attrset(COLOR_PAIR( COLOR_VOL2) | A_ALTCHARSET);      
            else  
               attrset(COLOR_PAIR( COLOR_VOL3) | A_ALTCHARSET);      
       mvaddch(Y_POS-1, i*((i+1) % 2) +X_POS * ((i+1) % 2 ),249); 
       if ( (dev_nr == DEV_COUNT-1) || (dev_nr == (DEV_COUNT-1)/2) ) 
          mvaddch(Y_POS+2, i*((i+1) % 2) +X_POS * ((i+1) % 2 ),249); 
       attrset( ( DEV_EXIST ? COLOR_PAIR(COLOR_ACT_SLIDE) | A_ALTCHARSET : COLOR_PAIR(COLOR_NACT_SLIDE) | A_ALTCHARSET | A_BOLD  )); 
       mvaddch(Y_POS,i+X_POS,205); 
       mvaddch(Y_POS+1,i+X_POS,205); 
   } 
   if (DEV_REC) 
   { 
      attrset( (REC_ON ? COLOR_PAIR(COLOR_REC_ON) | A_ALTCHARSET | A_BOLD : COLOR_PAIR(COLOR_REC_OFF) | A_ALTCHARSET | A_BOLD )); 
      mvaddch(Y_POS+1,X_POS - 10,254); 
   } 
 
 } 
 
/* draws basic screen */ 
void put_screen(void) 
{ 
   int pos; 
   char dummy[80]; 
   clear(); 
   wattrset(stdscr,COLOR_PAIR( COLOR_TITLE) | A_BOLD ); 
   sprintf(dummy,"%31cCAM %i.%i for Linux%32c",' ',VERSION_HIGH,VERSION_LOW,' '); 
   mvaddstr(0,0,dummy); 
   sprintf(dummy," Cpu's Audio Mixer %i.%i%18cauthor : Jan 'TWP' VANDENBERGHE (c)1994 ",VERSION_HIGH,VERSION_LOW,' '); 
   mvaddstr(24,0,dummy ); 
   attrset(A_BOLD); 
   mvaddstr(23,5,"Press `h` for help"); 
   status(" UNLOCKED "); 
   for (dev_nr = 0; dev_nr < DEV_COUNT;dev_nr++) 
   { 
       Draw_slide(); 
       if ( DEV_EXIST ) 
       { 
	  if (ioctl(mixer_fd, MIXER_READ(dev_nr), &pos) == -1 ) 
	  { 
	     perror("MIXER_READ : Error reading /dev/mixer"); 
	     endwin(); 
	     exit(-1); 
	  } 
       } 
       else 
	    pos = 0; 
       dev_vol[dev_nr][0] = (((getbits(pos,7,8) << 8) /1285) ) ; 
       if (STEREO) 
	  dev_vol[dev_nr][1] = (((getbits(pos,15,8) << 8) /1285) ); 
       else 
	  dev_vol[dev_nr][1] = dev_vol[dev_nr][0]; 
       if ( dev_vol[dev_nr][0] != 0 ) 
	  dev_vol[dev_nr][0]++; 
       if ( dev_vol[dev_nr][1] != 0 ) 
	  dev_vol[dev_nr][1]++; 
 
       if ( DEV_EXIST ) 
       { 
	  Draw_handle(4,0,0); 
	  if (  STEREO ) 
	     Draw_handle(4,0,1); 
       } 
 
       refresh(); 
   } 
} 
 
 
/* displays the help screen */
void help(void) 
{ 
   WINDOW *help_win; 
   char ch; 
   touchwin(stdscr); 
   help_win = newwin(15,50,5,15); 
   wattrset(help_win, COLOR_PAIR( COLOR_HELP) | A_BOLD ); 
   wclear(help_win); 
   leaveok(help_win,TRUE); 
   wborder(help_win,ACS_VLINE,ACS_VLINE,ACS_HLINE,ACS_HLINE,ACS_ULCORNER, \
   ACS_URCORNER,ACS_LLCORNER,ACS_LRCORNER); 
   mvwaddstr(help_win,2,2," Left/Right : Lower/Higher "); 
   mvwaddstr(help_win,3,2," Up/Down    : Previous/Next "); 
   mvwaddstr(help_win,5,2," l : Lock/Unlock "); 
   mvwaddstr(help_win,6,2," r : Record/Play "); 
   mvwaddstr(help_win,7,2," s : Save settings "); 
   mvwaddstr(help_win,8,2," g : Load settings "); 
   mvwaddstr(help_win,9,2," h : help "); 
   mvwaddstr(help_win,11,2," ESC/q : exit "); 
   mvwaddstr(help_win,13,8," Press key to leave help screen "); 
   wrefresh(help_win); 
   ch = wgetch(help_win); 
   delwin(help_win); 
   refresh(); 
} 

/* displays help at command line */ 
void comm_help(void) 
{ 
   printf("Usage: cam [OPTIONS]\n\n"); 
   printf("OPTIONS\n"); 
   printf("-v x,y : Set 'volume' to x (left ) and y (right)\n"); 
   printf("-b x,y : Set 'bass' to x (left ) and y (right)\n"); 
   printf("-t x,y : Set 'treble' to x (left ) and y (right)\n"); 
   printf("-s x,y : Set 'Synth' to x (left ) and y (right)\n"); 
   printf("-p x,y : Set 'pcm' to x (left ) and y (right)\n"); 
   printf("-S x,y : Set 'speaker' to x (left ) and y (right)\n"); 
   printf("-l x,y : Set 'line in' to x (left ) and y (right)\n"); 
   printf("-m x,y : Set 'microphone' to x (left ) and y (right)\n"); 
   printf("-c x,y : Set 'CD in' to x (left ) and y (right)\n"); 
   printf("-M x,y : Set 'mixer' to x (left ) and y (right)\n"); 
   printf("-P x,y : Set 'pcm2' to x (left ) and y (right)\n"); 
   printf("-r x,y : Set 'record' to x (left ) and y (right)\n"); 
   printf("-g     : restore the saved values\n"); 
   printf("-h     : display's this help\n"); 
   printf("\nNOTE : x and y are in range from 1 to 20\n"); 
} 

/* initializes the colors */ 
void make_colors(void) 
{ 
   start_color();
   if ( has_colors() )
   {  
      init_pair( COLOR_ACT_HANDLE, COLOR_BLUE , COLOR_BLACK); 
      init_pair( COLOR_NACT_HANDLE, COLOR_BLUE , COLOR_BLACK); 
      init_pair( COLOR_ACT_SLIDE, COLOR_WHITE , COLOR_BLACK); 
      init_pair( COLOR_NACT_SLIDE , COLOR_BLACK , COLOR_BLACK); 
      init_pair( COLOR_STATUS, COLOR_WHITE, COLOR_RED); 
      init_pair( COLOR_MSG, COLOR_YELLOW, COLOR_BLACK); 
      init_pair( COLOR_REC_ON, COLOR_GREEN, COLOR_BLACK); 
      init_pair( COLOR_REC_OFF, COLOR_RED, COLOR_BLACK); 
      init_pair( COLOR_TITLE, COLOR_YELLOW, COLOR_BLUE); 
      init_pair( COLOR_HELP, COLOR_YELLOW, COLOR_BLUE); 
      init_pair( COLOR_VOL1, COLOR_GREEN, COLOR_BLACK); 
      init_pair( COLOR_VOL2, COLOR_YELLOW, COLOR_BLACK); 
      init_pair( COLOR_VOL3, COLOR_RED, COLOR_BLACK); 
   }
   else
   {
      init_pair( COLOR_ACT_HANDLE, COLOR_WHITE , COLOR_BLACK); 
      init_pair( COLOR_NACT_HANDLE, COLOR_WHITE , COLOR_BLACK); 
      init_pair( COLOR_ACT_SLIDE, COLOR_WHITE , COLOR_BLACK); 
      init_pair( COLOR_NACT_SLIDE , COLOR_BLACK , COLOR_BLACK); 
      init_pair( COLOR_STATUS, COLOR_WHITE, COLOR_BLACK); 
      init_pair( COLOR_MSG, COLOR_WHITE, COLOR_BLACK); 
      init_pair( COLOR_REC_ON, COLOR_WHITE, COLOR_BLACK); 
      init_pair( COLOR_REC_OFF, COLOR_BLACK, COLOR_BLACK); 
      init_pair( COLOR_TITLE, COLOR_BLACK, COLOR_WHITE); 
      init_pair( COLOR_HELP, COLOR_WHITE, COLOR_BLACK); 
      init_pair( COLOR_VOL1, COLOR_WHITE, COLOR_BLACK); 
      init_pair( COLOR_VOL2, COLOR_WHITE, COLOR_BLACK); 
      init_pair( COLOR_VOL3, COLOR_WHITE, COLOR_BLACK); 
   }
} 
