#include "snd.h"

int round(float x)
{
  int i;
  i=x;
  if ((x-i) > 0.5) return(i+1);
  return(i);
}

char *copy_string (char *str)
{
  char *newstr = NULL;
  if (str)
    {
      newstr = (char *)calloc(strlen(str)+1,sizeof(char));
      strcpy(newstr,str);
    }
  return(newstr);
}
      
void snd_error (char *msg)
{
  fprintf(stderr,msg);
}

char *filename_without_home_directory(char *name)
{
  /* since we don't want to mess with freeing these guys, I'll just return a pointer into the name */
  /* and for now, to heck with home */
  int i,len,last_slash;
  last_slash = 0;
  len = strlen(name);
  for (i=0;i<len-1;i++) if (name[i] == '/') last_slash = i+1;
  return((char *)(name+last_slash));
}

char *just_filename(char *name)
{
  char *nodir;
  int i,len;
  nodir = copy_string(filename_without_home_directory(name));
  len = strlen(nodir);
  for (i=0;i<len;i++) if (nodir[i] == '.') {nodir[i] = '\0'; break;}
  return(nodir);
}

#ifndef sqr
float sqr(float a) {return(a*a);}
#endif

float cube (float a) {return(a*a*a);}

static char prtbuf[512];

char *prettyf(float num, int tens)
{ /* try to prettify float display -- if tens<0, return int */
  int fullf,len,i;
  float rounder;
  char *newval,*sp,*sn,*zp;
  zp=NULL;
  if (num < 0.0) rounder = -.49; else rounder = .49;
  if (tens < 0)
    {
      fullf=num+rounder;
      sprintf(prtbuf,"%d",fullf);
      len=strlen(prtbuf);
      newval=(char *)calloc(len+1,sizeof(char));
      strcpy(newval,prtbuf);
      return(newval);
    }
  fullf = num;
  if ((num-fullf) == 0.0) 
    {
      if (num<100.0)
	sprintf(prtbuf,"%d%c0",fullf,snd_string_decimal);
      else sprintf(prtbuf,"%d",fullf);
      len=strlen(prtbuf);
      newval=(char *)calloc(len+1,sizeof(char));
      strcpy(newval,prtbuf);
      return(newval);
    }
  if (num > 1000)
    {
      sprintf(prtbuf,"%d%c%d",fullf,snd_string_decimal,(int)((num-fullf)*pow(10,tens)));
      len=strlen(prtbuf);
      newval=(char *)calloc(len+1,sizeof(char));
      strcpy(newval,prtbuf);
      return(newval);
    }
  fullf = num*pow(10,tens+1)+rounder;
  if (fullf == 0) 
    {
      /* will be freed later, so can't return a constant */
      newval=(char *)calloc(2,sizeof(char));
      newval[0] = '0';
      newval[1] = '\0';
      return(newval);
    }
  sprintf(prtbuf,"%d",fullf);
  len=strlen(prtbuf);
  newval=(char *)calloc(len+10,sizeof(char));
  sn = newval;
  sp = prtbuf;
  if ((*sp) == '-') {(*sn) = (*sp); sn++; sp++; len--;}
  if (len >= (tens+1))
    {
      for (i=0;i<len-tens-1;i++) {(*sn)=(*sp); sn++; sp++;}
      (*sn)=snd_string_decimal; sn++;
    }
  else
    {
      (*sn) = '0';
      sn++;
      (*sn) = snd_string_decimal;
      sn++;
      for (i=0;i<abs(len-tens-1);i++) 
	{
	  (*sn) = '0';
	  sn++;
	}
    }
  if (tens > 3) tens = 3;  /* 3 or 4 is enough for sound file work */
  for (i=0;i<=tens;i++) 
    {
      if (!(*sp)) break;
      (*sn)=(*sp); 
      if ((!zp) || ((*sn) != '0')) zp = sn;
      sn++; 
      sp++;
    }
  if (zp) {sn=zp;} else {(*sn)='0';}
  sn++;
  (*sn) = '\0';
  return(newval);
}

int disk_space_p(snd_info *sp, int fd, int bytes, int other_bytes)
{
  int kfree,kneeded,kother,go_on;
  kfree = disk_kspace(fd);
  if (kfree < 0) {sprintf(prtbuf,strerror(errno)); report_in_minibuffer(sp,prtbuf); return(NO_PROBLEM);}
  kneeded = bytes >> 10;
  if (kfree < kneeded)
    {
      if (other_bytes > 0)
	{
	  kother = other_bytes >> 10;
	  if (kother > kfree)
	    {
	      sprintf(prtbuf,snd_string_no_room_but_we_try,kfree<<10);
	      report_in_minibuffer(sp,prtbuf);
	      return(HUNKER_DOWN);
	    }
	}
      sprintf(prtbuf,snd_string_no_room_go_on_p,kfree<<10);
      go_on = snd_yes_or_no_p(sp->state,prtbuf);
      if (!go_on) return(GIVE_UP);
      report_in_minibuffer(sp,snd_string_going_on);
      return(BLIND_LEAP);
    }
  return(NO_PROBLEM);
}

int snd_checked_write(snd_state *ss, int fd, unsigned char *buf, int bytes)
{
  /* clm checked_write assumes clm descriptors are around and writes errors to stderr */
  int bytes_written,kfree;
  kfree = disk_kspace(fd);
  if (kfree < 0) {sprintf(prtbuf,strerror(errno)); snd_printf(ss,prtbuf); return(-1);}
  if (kfree < (bytes>>10))
    {
      sprintf(prtbuf,snd_string_no_room,kfree<<10,bytes);
      snd_yes_or_no_p(ss,prtbuf);
      return(-1);
    }
  bytes_written = write(fd,buf,bytes);
  if (bytes_written != bytes)
    {
      sprintf(prtbuf,snd_string_write_failed,strerror(errno));
      snd_printf(ss,prtbuf);
      return(-1);
    }
  return(bytes_written);
}

void fill_number(char *fs, char *ps)
{
  int i,j;
  j=strlen(fs);
  if (j>4) j=4;
  if (j<4) {ps[4] = '\0'; ps[3]='0'; ps[2]='0'; ps[1]=snd_string_decimal;}
  if ((*fs) == snd_string_decimal) {*ps++ = '0'; if (j==4) j=3;}
  for (i=0;i<j;i++) (*ps++) = (*fs++);
}

static int sect_ctr = 0;
char *shorter_tempnam(char *dir,char *prefix)
{
  /* tempnam turns out names that are inconveniently long */
  char *str;
  str = (char *)calloc(256,sizeof(char));
  if (dir) 
    sprintf(str,"%s/sect-%d.snd",dir,sect_ctr++);
  else sprintf(str,"/var/tmp/sect-%d.snd",sect_ctr++);
  return(str);
}

