/* xdf version 1.0 July 5th 1996
   by Georg C. F. Greve (greve@fusebox.hanse.de)
   */

/*{{{  Header  */

/*Xlib includes */
#include <X11/Xlib.h>
#include <xview/xview.h>
#include <xview/frame.h>
#include <xview/panel.h>
#include <xview/notify.h>
#include <xview/cms.h>
#include <xview/svrimage.h>

/*Standard C++ includes*/
#include <stdio.h>
#include <iostream.h>
#include <strstream.h>
#include <syscall.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/vfs.h>
#include <unistd.h>
#include <ctype.h>
#include <pwd.h>
#include <stdlib.h>
#include <assert.h>
#include <mntent.h>
#include <sys/mount.h>
#include <linux/fs.h>

#include "xdf.H"
#include "galaxy.xbm"
/*}}}*/

/*{{{  Initialisation (Main)  */
int main(int argc, char* argv[]){

  prgname = argv[0];

  XrmInitialize();
  xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);

  Server_image image = (Server_image) xv_create ( (Xv_Screen) NULL, SERVER_IMAGE,
						  XV_WIDTH, galaxy_width,
						  XV_HEIGHT, galaxy_height,
						  SERVER_IMAGE_X_BITS, galaxy_bits,
						  NULL); 
  

  frame = (Frame) xv_create ( (long unsigned int) NULL, FRAME, 
			      FRAME_LABEL, "XDiskFree", 
			      NULL);

  Icon icon = (Icon) xv_create(frame, ICON,
			       ICON_IMAGE, image,
			       XV_X, galaxy_width,
			       XV_Y, galaxy_height,
			       NULL);

  xv_set(frame, FRAME_ICON, icon, NULL);

  panel = (Panel) xv_create (frame, PANEL, 
			     WIN_ROW_GAP, 8,
			     WIN_COLUMN_GAP, 115,
			     NULL);


/*{{{  Get Information and create Panel  */
  int row = 0;

  fstab = setmntent( "/etc/fstab", "r");

  mountpoints=0;
  while ( table = getmntent( fstab ) ) {
    if ( strcmp( "swap", table->mnt_dir) && strcmp( "/proc", table->mnt_dir) 
#ifdef NO_NFS
	 && strcmp( "nfs", table->mnt_type )
#endif
	 ){
      par_table[mountpoints] = new Partition;
      par_table[mountpoints]->name = new char[ strlen(table->mnt_dir) + 1 ];
      strcpy(par_table[mountpoints]->name, table->mnt_dir);
      statfs(par_table[mountpoints]->name, &stat_buffer);
      par_table[mountpoints]->last_max_value = 
	par_table[mountpoints]->max_value = (stat_buffer.f_blocks*stat_buffer.f_bsize)/1024;
      par_table[mountpoints]->last_value = 
	par_table[mountpoints]->max_value - ((stat_buffer.f_bfree*stat_buffer.f_bsize)/1024);
      create_label( (char*) par_table[mountpoints]->fullstring , (long) par_table[mountpoints]->last_value );
      mountpoints++;
    }
  }
  endmntent( fstab );

  for (int i = 0; i < mountpoints ; ++i){

    if ( strlen(par_table[i]->name) <= 16 ) strcpy(par_table[i]->panelname, par_table[i]->name);
    else {
      int spos = strlen(par_table[i]->name);
      for ( int tpos = 19 ; tpos >= 0 ; tpos-- ){
	if ( tpos < 3 ) par_table[i]->panelname[tpos] = '.';
	else par_table[i]->panelname[tpos] = par_table[i]->name[spos--];
      }
    }

    par_table[i]->name_item = xv_create(panel, PANEL_MESSAGE,
					PANEL_LABEL_STRING, par_table[i]->panelname,
					XV_X, xv_col(panel, 0),
					XV_Y, xv_row(panel, row),
					PANEL_INACTIVE, TRUE,
					NULL);

    par_table[i]->item = xv_create(panel, PANEL_GAUGE,
				   PANEL_GAUGE_WIDTH, 250,
				   PANEL_VALUE, par_table[i]->last_value,
				   PANEL_MIN_VALUE, 0,
				   PANEL_MAX_VALUE, par_table[i]->max_value,
				   PANEL_LABEL_STRING, par_table[i]->fullstring,
				   PANEL_TICKS, 11,
				   PANEL_INACTIVE, TRUE,
				   PANEL_LABEL_BOLD, FALSE,
				   XV_X, xv_col(panel, 1),
				   XV_Y, xv_row(panel, row++),
				   NULL);

  }

  window_fit(panel);
  window_fit(frame);
  xv_set(frame, XV_SHOW, TRUE, NULL);

/*}}}*/

/*{{{  See which ones are mounted and change Panel accordingly  */

  for ( int i = 0 ; i < mountpoints ; ++i ){
    par_table[i]->last_status = par_table[i]->status;
    par_table[i]->status = TRUE;
  }

  mtab = setmntent( "/etc/mtab", "r");
  while ( table = getmntent( mtab ) ){
    for ( int i = 0 ; i < mountpoints ; ++i ){
      if ( !strcmp(par_table[i]->name, table->mnt_dir) ) par_table[i]->status = FALSE;
    }
  }
  endmntent( mtab );

  for ( int i = 0 ; i < mountpoints ; ++i ){
      if ( par_table[i]->status == TRUE ) {
	xv_set(par_table[i]->item, PANEL_MAX_VALUE, 1, NULL);
	xv_set(par_table[i]->item, PANEL_VALUE, 0,NULL);
	par_table[i]->last_max_value=1;
	par_table[i]->max_value = 1;
	par_table[i]->last_value = 0 ;
	xv_set ( par_table[i]->item, PANEL_LABEL_STRING, "________", NULL);
      }
      xv_set(par_table[i]->name_item, PANEL_INACTIVE, par_table[i]->status, NULL);
      xv_set(par_table[i]->item, PANEL_INACTIVE, par_table[i]->status, NULL);
  }

/*}}}*/

  timer.it_value.tv_usec = 500 * 1000 ;
  timer.it_interval.tv_usec = 500 * 1000 ;
  notify_set_itimer_func(frame, (Notify_func) timer_routine, ITIMER_REAL,
			 &timer, NULL);

  xv_main_loop (frame);
  return TRUE;

}
/*}}}*/

/*{{{  Subroutines  */
void quit(){
  xv_destroy_safe(frame);
}
inline void create_label(char* buffer,const long value){
  char temp[20];
  ostrstream OSS(temp, 20, ios::out );  
  OSS.seekp(ios::beg);
  OSS << value << ends;

  int index;
  for ( index = 0 ; index < 8-strlen(temp) ; ++index ) buffer[index]='_';
  strcpy( &buffer[index], temp );

  return;
}
Notify_value timer_routine(){

  for ( int i = 0 ; i < mountpoints ; ++i ){
    par_table[i]->last_status = par_table[i]->status;
    par_table[i]-> status = TRUE;
  }

  mtab = setmntent( "/etc/mtab", "r");
  while ( table = getmntent( mtab ) ){
    for ( int i = 0 ; i < mountpoints ; ++i ){
      if ( !strcmp(par_table[i]->name, table->mnt_dir) ) par_table[i]->status = FALSE;
    }
  }
  endmntent( mtab );

  for ( int i = 0 ; i < mountpoints ; ++i ){
    if ( par_table[i]->last_status != par_table[i]->status) {
      if ( par_table[i]->status == TRUE ) {
	xv_set(par_table[i]->item, PANEL_MAX_VALUE, 1, NULL);
	xv_set(par_table[i]->item, PANEL_VALUE, 0,NULL);
	par_table[i]->last_max_value=1;
	par_table[i]->max_value = 1;
	par_table[i]->last_value = 0 ;
	xv_set ( par_table[i]->item, PANEL_LABEL_STRING, "________", NULL);
      }
      xv_set(par_table[i]->name_item, PANEL_INACTIVE, par_table[i]->status, NULL);
      xv_set(par_table[i]->item, PANEL_INACTIVE, par_table[i]->status, NULL);
    }
  }

  for ( int i = 0 ; i < mountpoints ; ++i ){

    if ( par_table[i]->status == FALSE ){
      statfs(par_table[i]->name, &stat_buffer);
      par_table[i]->max_value = (stat_buffer.f_blocks*stat_buffer.f_bsize)/1024;
      if ( par_table[i]->max_value != par_table[i]->last_max_value )
	xv_set ( par_table[i]->item, PANEL_MAX_VALUE, par_table[i]->max_value, NULL);
      par_table[i]->last_max_value = par_table[i]->max_value;
      
      long new_value = par_table[i]->max_value - ((stat_buffer.f_bfree*stat_buffer.f_bsize)/1024);
      if ( par_table[i]->last_value != new_value ){
	
	create_label( (char*) par_table[i]->fullstring , (long) new_value );
	xv_set ( par_table[i]->item, PANEL_LABEL_STRING, par_table[i]->fullstring, NULL);
	par_table[i]->last_value = new_value;
	xv_set ( par_table[i]->item, PANEL_VALUE, par_table[i]->last_value, NULL);

      }
    }
  }

  return NOTIFY_DONE;
}
/*}}}*/




