/***************************************************************************
 *   copyright           : (C) 2005 by Hendrik Sattler                     *
 *   mail                : post@hendrik-sattler.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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <helper.h>

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#if ! ( defined(OS2_API) || defined(WINDOWS_API) )
#define UNIX_API 1
#endif

#if defined(UNIX_API)
#include <sys/ioctl.h>
#include <termios.h>
static long console_width_sys (int fd) {
  struct winsize wsize;
#if defined(TIOCGWINSZ)
  if (ioctl(fd,TIOCGWINSZ,&wsize) == 0)
    return wsize.ws_col;
#endif
  return 0;
}

#else
#if defined(WINDOWS_API)
#include <w32compat.h>
static long console_width_sys (int fd) {
  HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
  CONSOLE_SCREEN_BUFFER_INFO i;
  
  if (GetConsoleScreenBufferInfo(h,&i))
    /* Window command window jumps to a new line before
     * recognizing the character is a newline character.
     * So we must use 79 for a width of 80.
     */
    return i.dwSize.X-1; 

  return 0;
}

#else
static long console_width_sys (int fd) {
  return 0;
}

#endif
#endif


long console_width(int fd) {
  char* cols = getenv("COLUMNS");
  long width = console_width_sys(fd);
  char* temp = NULL;
  
  if (!width && cols)
    width = strtol(cols,&temp,10);

  return (width)? width : 78;
}

void console_print_status (int fd,
			   const char* text,
			   size_t textlen,
			   const unsigned long* current,
			   const unsigned long* total,
			   unsigned int fcount)
{
  size_t width = console_width(fd);
  size_t w = 0;
  size_t barlen = width;
  unsigned int c = 0;
  size_t i = 0;
  size_t k = 0;
  char numout[6+1];
  unsigned long lcurrent, ltotal;

  if (current == NULL || total == NULL || fcount == 0)
    return;

  write(fd,"\r",1);

  if (str_len(text) && textlen) {
    write(fd,text,textlen);
    i = strn_width(text,textlen);
    barlen -= i;
    w += i;
  }
  write(fd," ",1);
  barlen -= 1 - (i+1)%fcount;
  w += 1;

  barlen = (barlen/fcount)-(sizeof(numout)-1)-2;
  for (; c < fcount; ++c) {
    lcurrent = current[c];
    ltotal = total[c];
    if (ltotal == 0) {
      if (lcurrent == 0) lcurrent = 1;
      ltotal = lcurrent;
    }

    /* print status bar */
    write(fd,"[",1);
    w += 1;
    k = 0;
    for (i = 0; i < barlen; ++i) {
      if (lcurrent != 0) {
	if (k < ((lcurrent*barlen)/ltotal)) {
	  write(fd,"=",1);
	} else if (k == ((lcurrent*barlen)/ltotal)) {
	  if (lcurrent == ltotal) write(fd,"=",1);
	  else write(fd,">",1);
	} else {
	  write(fd," ",1);
	}
	++k;
      } else {
	write(fd," ",1);
      }
    }
    w += barlen;
    write(fd,"]",1);
    w += 1;
    
    /* status in numbers */
    snprintf(numout,sizeof(numout)," %3lu%% ",(100*lcurrent)/ltotal);
    write(fd,numout,strlen(numout));
    w += strlen(numout);
  }
  while (w++ < width) write(fd," ",1);
  write(fd,"\r",1);
}
