/*
 * $Id: base64.c,v 1.7 2003/11/25 09:28:27 alphix Exp $
 *
 * This file is part of Ample.
 *
 * Ample 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.
 *
 * Ample 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 Ample; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdlib.h>
#include <string.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#include "ample.h"
#include "base64.h"

static int 
valof(char c) 
{
        char *alphabet =
		"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	char *tmp = alphabet;
	int i = 0;

	if (c == '\0')
		return -1;
	
	while(TRUE) {
		if (*tmp == '\0')
			return -1;
		if (*tmp == c)
			return i;
		i++;
		tmp++;
	}
}

bool 
isbase64(char c)
{
	if(valof(c) >= 0)
		return(TRUE);
	else
		return(FALSE);
}

static void 
nextchunk(char ** c, char * chunk) 
{
	int i;
	int b64val[4];

	for(i=0; i < 4; i++) {
		if(**c != '\0') {
			b64val[i] = valof(**c);
			(*c)++;
		} else {
			b64val[i] = '\0';
		}
	}
	
	*(chunk + 0) = CHAR1(b64val[0],b64val[1]);
	*(chunk + 1) = CHAR2(b64val[1],b64val[2]);
	*(chunk + 2) = CHAR3(b64val[2],b64val[3]);
	
}

char * 
b64dec(char * msg) 
{
	char * tmp = msg;
	char * buffer;
	char chunk[4];

	if(*tmp == '\0')
		return NULL;

	memset(chunk,0,sizeof(chunk));
	buffer = (char *)malloc(strlen(msg) + 1);
	*buffer = '\0';
	
	while(*tmp != '\0') {
		nextchunk(&tmp,chunk);
		strcat(buffer,chunk);
	}
	
	return buffer;
}

/* I stored this here for now, might be useful later - David */
 /*
 * Sends a sequence of digital silence that is at least as long as duration
 * and probably shorter than duration + max length of a frame
 * (which is something like 26.126 milliseconds)
 */
/*
static bool 
sendsilence(float duration, FILE *to, int *metaflag)
{
	int i = 0;
*/
	/* FrameSize = 144 * BitRate / (SampleRate + Padding) */
	/*double framesize = (144 * 128*1000) / (44.1*1000 + 0);*/
	/* Frames = Time * SampleRate / (FrameSize * 8) */
/*	int max = (int)ceil(((double)duration * 128*1000) / (framesize * 8));*/
	/* How much have we drifted from FrameSize bytes / frame */
/*	double diff = 0;

	char framebody[410];
	char firstheaders[2][8] = {{0xFF,0xFB,0x92,0x04,0x00,0x00,0x00,0x00},
				   {0xFF,0xFB,0x92,0x04,0xBF,0x00,0x07,0xE8}};
	char shortheader[8]     =  {0xFF,0xFB,0x90,0x04,0xFF,0x80,0x0B,0xE8};
	char longheader[8]      =  {0xFF,0xFB,0x92,0x04,0xFF,0x80,0x0B,0xF0};
	char framebegin[28]     =  {0x00,0x69,0x00,0x00,0x00,0x00,0x00,0x00,
				    0x0D,0x20,0x00,0x00,0x00,0x00,0x00,0x01,
				    0xA4,0x00,0x00,0x00,0x00,0x00,0x00,0x34,
				    0x80,0x00,0x00,0x00};

	memset(framebody, 0xFF, 410);
	memcpy(framebody, framebegin, 28);
	debug(3, "sending %i frames of digital silence", max);

	while(i < max) {
		diff += 418 - framesize;

		if(i < 2) {
			senddata(to, firstheaders[i], 8, metaflag);
			senddata(to, framebody, 410, metaflag);
		} else if(diff < 1) {
			senddata(to, longheader, 8, metaflag);
			senddata(to, framebody, 410, metaflag);
		} else {
			diff--;
			senddata(to, shortheader, 8, metaflag);
			senddata(to, shortheader, 409, metaflag);
		}
		
		i++;
	}

	return(TRUE);
} 
*/
