/*
    This file is part of Bemused.

    Bemused 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.

    Bemused 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 Bemused; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

	Copyright (C) 2003 Ashley Montanaro and Daniel Winter.
	Affix stack fixes: Andrei Emeltchenko and Dmitri Kasatkin.
*/

#include <stdlib.h>
#include <iostream>
#include <fstream>

#include <errno.h>
#include <signal.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>

#include <netinet/in.h>
#include <arpa/inet.h>
#include <resolv.h>
#include <netdb.h>
#include <sys/socket.h>

#ifndef AFFIX /* Bluez BT stack */
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
#else /* Affix BT stack */
#include <affix/btcore.h>
#include <affix/sdpclt.h>
#include <affix/sdpsrv.h>
#endif

#include <xmmsctrl.h>

#include "BemusedServerDlg.h"

using namespace std;

/* Test modes */
enum {
	SEND,
	RECV,
	RECONNECT,
	MULTY,
	DUMP,
	CONNECT,
	CRECV,
	LSEND
};

const static char bookpath[] = "Bookmarks/";
char wbookpath[1024]; // has any paths added or removed


#ifdef AFFIX

BD_ADDR bdaddr;

void baswap(BD_ADDR *dst, BD_ADDR *src)
{
	unsigned char *d = (unsigned char *) dst;
	unsigned char *s = (unsigned char *) src;
	int i;

	for (i = 0; i < 6; i++)
		d[i] = s[5 - i];
}

char *batostr(BD_ADDR *ba)
{
	static char str[2][18];
	static int i = 1;

	i ^= 1;
	sprintf(str[i], "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
	        ba->bda[0], ba->bda[1], ba->bda[2],
		ba->bda[3], ba->bda[4], ba->bda[5]);

	return str[i];
}

static int	srvHandle = -1;
static sdpsvc_t	*svcRec;

void sdpreg_cleanup(void)
{
	sdp_close(srvHandle);
	sdp_cleanup();
}


int sdpreg_init(void)
{
        // initialize the SDP internal data structures

        if (sdp_init(SDP_SVC_PROVIDER) != 0)
                return -1;
        srvHandle = sdp_connect_local();
        if (srvHandle < 0)
                return srvHandle;
        return 0;
}

int sdpreg_serialport(int port)
{
        int	status = -1;

	svcRec = sdp_create_rfcomm_svc(SDP_UUID_SERIAL_PORT, 0x0000,
                       SDP_UUID_SERIAL_PORT,"Bemused", "Coolstuff", "Music",port);
    
	
        if (svcRec == NULL) {
                BTERROR("sdp_create_svc failed");
                return -1;
        }
        status = sdp_register_service(srvHandle, svcRec);
        if (status != 0) {
                BTERROR("sdp_register_service failed");
                sdp_free_svc(svcRec);
                return -1;
        }
        return 0;
}

int sdpreg_unregister()
{
	intstatus;
	if (!svcRec) return 0;
	status = sdp_delete_service(srvHandle, svcRec);
	sdp_free_svc(svcRec);
	svcRec = NULL;
	return 0;
}


#else

bdaddr_t bdaddr;
#endif


/////////////////////////////////////////////////////////////////////////////
// CDirTreeNode class

CDirTreeNode::CDirTreeNode()
	{
	iFirstChild = NULL;
	iNextSibling = NULL;
	iParent = NULL;
	iFileName = NULL;
	iNodeType = iFileType = 0x0;
	iWrittenToBuffer = false;
	}

CDirTreeNode::~CDirTreeNode()
	{
	delete iFirstChild;
	delete iNextSibling;
	delete iFileName;
	}

/////////////////////////////////////////////////////////////////////////////
// CBemusedServerDlg dialog

CBemusedServerDlg::CBemusedServerDlg()
	
	{
	iDirTreeRoot = iDirTreeCurrentNode = NULL;
	lastTime = 0;
	}

CBemusedServerDlg::~CBemusedServerDlg()
	{
	delete iDirTreeRoot;
  close(iCommHandle);
  close(socket1);
  }

bool CBemusedServerDlg::OnInitDialog(bool daemonize)
{
	Log("Welcome to Bemused 1.73\r\n");
	Log("Copyright Ashley Montanaro 2003\r\n");
	Log("Linux port from Daniel Winter\r\n\r\n");

	ReadIniFile();
	socket1=BluetoothConnectToSocket(channel);

	CheckWinamp("Blub");
	//xmms_remote_set_main_volume(0,47);
	
	if (daemonize)
	{
		Log("daemonizing\n");
		if (daemon(0, 1) < 0)
		{
			perror("daemon");
			exit(1);
		}
		fclose (stdout);
	}

	while(1) 
	{
		iCommHandle=BluetoothWaitforConnect(socket1);
		 HandleBluetooth();
	}
	return true;  
	}


void CBemusedServerDlg::ReadIniFile()
	{
  bool mp3set=false,autoset=false,xmmsdirset=false,fastforbackspeedset=false;
  bool	channelset=false,bookmarkset=false,bookmarkread=false,portset=false;
  char row[1025],wert[1025],einstellung[100];
  tcpport=7654;
  channel=10;
  tcp=false;
  strcpy(winampPath,"xmms");
  startAutomatically=1;
  ifstream conffile("/etc/bemused.conf");
  if (!conffile) {
    Log("Could not read the configfile /etc/bemused.conf\n\r");
    exit(2);
  }
  while (conffile.getline(row,1024))
  {
    if (!(row[0]=='#') && !(row[0]=='\0'))
    {
     strcpy(einstellung,strtok(row, "="));
     strcpy(wert,strtok(NULL,"="));
     if (!strcmp(einstellung,"mp3dir"))
     {
       strcpy(mp3Dirs,wert);
       mp3set=true;
     }
     if (!strcmp(einstellung,"tcp"))
     {
       int tmptcp;
       tmptcp=atoi(wert);
       if (tmptcp==1) tcp=true;
     }
     if (!strcmp(einstellung,"channel"))
     {
       channel=atoi(wert);
       channelset=true;
     }
     if (!strcmp(einstellung,"tcpport"))
     {
       tcpport=atoi(wert);
       portset=true;
     }
     if (!strcmp(einstellung,"fastforbackspeed"))
     {
       fastforbackspeed=atoi(wert);
       fastforbackspeedset=true;
     }
     if (!strcmp(einstellung,"xmmsdir"))
     {
       strcpy(winampPath,wert);
       xmmsdirset=true;
     }
     if (!strcmp(einstellung,"bookmarkfile"))
     {
       strcpy(bookmarkfile,wert);
       bookmarkset=true;
       bookmarkread=false;
     }
     if (!strcmp(einstellung,"autostartxmms"))
     {
       if (!strcmp(wert,"1")) startAutomatically=1; else startAutomatically=0;
       autoset=true;
     }
   }
  }
  conffile.close();
  if (!(mp3set))
    {
      Log("Configfile is not written correctly\n\r");
      exit(3);
    }
  if ((!channelset) && (!tcp))
   {
     Log("Warning: No channel defined in config file using default=10\n\r");
   }
   if ((!portset) && tcp)
   {
     Log("Warning: No port defined in config file using default=7654\n\r");
   }

  // Read in bookmarks if we have them
  nobookmarks = 0;
  if (bookmarkset)
    {
      ifstream bookfile(bookmarkfile);
      if (!bookfile) {
         Log("Could not read the bookmakrs file %s\n",bookmarkfile);
         exit(2);
      }

      while (bookfile.getline(row,1024))
        {
          if (!(row[0]=='#') && !(row[0]=='\0'))
             {
		strcpy(einstellung,strtok(row, "="));
                strcpy(wert,strtok(NULL,"="));

		// Trim any spaces out
		while( einstellung[strlen(einstellung)-1]==' ' )
		   {
		       einstellung[strlen(einstellung)-1] = '\0';
		   }
		while( wert[strlen(wert)-1]==' ' )
		   {
		       wert[strlen(wert)-1] = '\0';
		   }
		char altwert[1025];
		while( wert[0]==' ' )
		  {
	             strcpy(altwert,&wert[1]);
		     strcpy(wert,altwert);
		  }

		Log("I have a bookmark \"%s\" of \"%s\"\n",einstellung,wert);

		// Save this
		strcpy(bookmarks[nobookmarks],wert);
		strcpy(bookmarktitles[nobookmarks],einstellung);
		nobookmarks++;
             }
	}
    }
	if (!fastforbackspeedset) fastforbackspeed=10000;
	}



void CBemusedServerDlg::HandleBluetooth()
	{
	iExitNow = false;
	do {
		ReadBluetoothCommand();
		} while (!iExitNow);
	close(iCommHandle);
	}

bool CBemusedServerDlg::WriteFile(int handle,unsigned char* buffer,int maxbytes, long unsigned int* byteswritten,int* bla)
  {
  long unsigned int b;
  int br;
  br=write(handle,(void*)buffer,maxbytes);
  if (br==-1) {
     return false;
     }
     else {
     b=(long unsigned int)(br);
     *(byteswritten)=b;
     return true;
  }
  }


bool CBemusedServerDlg::WriteFile(int handle, char* buffer,int maxbytes, long unsigned int* byteswritten,int* bla)
  {
  long unsigned int b;
  int br;
  br=write(handle,(void*)buffer,maxbytes);
  if (br==-1) {
     return false;
     }
     else {
     b=(long unsigned int)(br);
     *(byteswritten)=b;
     return true;
  }
  }

bool CBemusedServerDlg::ReadFile(int handle,unsigned char* buffer,int maxbytes,long unsigned int* bytesread,int* bla)
  {
    long unsigned int b;
    int br;
    br=recv(handle, (void*)buffer, maxbytes,0);
    if (br<=0) {
      return false;
      }
      else {
      b=(long unsigned int)(br);
      *(bytesread)=b;
      return true;
      }

  }


bool CBemusedServerDlg::ReadFile(int handle,char* buffer,int maxbytes,long unsigned int* bytesread,int* bla)
  {
    long unsigned int b;
    int br;
    br=recv(handle, (void*)buffer, maxbytes,0);
    if (br<=0) {
      return false;
      }
      else {
      b=(long unsigned int)(br);
      *(bytesread)=b;
      return true;
      }

  }

void CBemusedServerDlg::ReadBluetoothCommand()
	{
	char buffer[5];
	unsigned long bytes_read = 0;

	memset(buffer, 0, 5);
	if (!ReadFile(iCommHandle, buffer, 4, &bytes_read, NULL))
		{

		if (!tcp) Log("Couldn't read command: %s\r\n", GetLastError());
		 else Log("Couldn't read command: Probably peer closed connection\r\n");
		iExitNow = true;
		}
	else
		{
//		MessageBox(buffer);

	CheckWinamp("blub");

	// List "neutral" commands first
	if (!strcmp(buffer, "LIST"))
			WriteListToPhone();
		else if (!strcmp(buffer, "DLST"))
			WriteDirectoryListToPhone();
		else if (!strcmp(buffer, "PLST"))
			WritePlaylistToPhone();
		else if (!strcmp(buffer, "FINF"))
			GetFileInfo();
		else if (!strcmp(buffer, "DOWN"))
			DownloadFile();
		else if (!strcmp(buffer, "VOLM"))
			SetVolume();
		else if (!strcmp(buffer, "CHCK"))
			Check();
		else if (!strcmp(buffer, "VERS"))
			Version();
		else if (!strcmp(buffer, "GVOL"))
			GetVolume();
		else if (!strcmp(buffer, "INFO")) 
			WriteInfoToPhone();
		else if (!strcmp(buffer, "INF2")) 
			WriteInf2ToPhone();
		else if (!strcmp(buffer, "DINF"))
			WriteDetailedInfoToPhone();
		else if (!strcmp(buffer, "RMAL"))
			RemoveAllFromPlaylist();
		else {
			// Put it in braces to avoid extraneous Log output
			// Don't stop at end if any other command is executed
			iStopEnd = false;
			
			if (!strcmp(buffer, "PLAY"))
				PlayFile(false);
			else if (!strcmp(buffer, "LADD"))
				PlayFile(true);
			else if (!strcmp(buffer, "STOP"))
				Stop(true);
			else if (!strcmp(buffer, "FADE"))
				FadeOut();	
			else if (!strcmp(buffer, "STEN")) {
				Log("Will stop at start of next song\n");
				iStopEnd=true;
			} else if (!strcmp(buffer, "PAUS"))
				Pause();
			else if (!strcmp(buffer, "STRT"))
				Play();
			else if (!strcmp(buffer, "SLCT"))
				SelectInPlaylist();
			else if (!strcmp(buffer, "PREV"))
				PreviousTrack();
			else if (!strcmp(buffer, "NEXT"))
				NextTrack();
			else if (!strcmp(buffer, "FFWD"))
				FastForward();
			else if (!strcmp(buffer, "SEEK"))
				SetSeek();
			else if (!strcmp(buffer, "RWND"))
				Rewind();
			else if (!strcmp(buffer, "SHFL"))
				Shuffle();
			else if (!strcmp(buffer, "REPT"))
				Repeat();
			else if (!strcmp(buffer, "SHUT"))
				ShutDown();
			else if (!strcmp(buffer, "EXIT"))
				exit(0);
			else
				Log("Read unknown command \"%s\"\r\n", buffer);
		}
 }
}

void CBemusedServerDlg::ReadDir(char* aDir, CDirTreeNode* aNode, bool aRecursive)
	{
	char fileNameBuf[MAX_PATH+1];
	sprintf(fileNameBuf, "%s/*.*", aDir);

  DIR *dir;
  struct dirent *dirzeiger;
  struct stat attribut;

  if ((dir=opendir(aDir)) == NULL)
    {
		Log("Couldn't open \"%s\"\r\n", aDir);
		return;
    }

	int foundCount = 0;

	CDirTreeNode* currentNode = aNode;


	while((dirzeiger=readdir(dir)) != NULL) {
		if (!strcmp((*dirzeiger).d_name, ".") || !strcmp((*dirzeiger).d_name, ".."))
			continue;

		if (foundCount == 0)
			{
			aNode->iFirstChild = new CDirTreeNode;
			aNode->iFirstChild->iParent = currentNode;
			currentNode = aNode->iFirstChild;
			currentNode->iNodeType = 0x1; // child
			}
		else
			{
			currentNode->iNextSibling = new CDirTreeNode;
			currentNode->iNextSibling->iParent = currentNode->iParent;
			currentNode = currentNode->iNextSibling;
			currentNode->iNodeType = 0x3; // sibling
			}

		foundCount++;

		sprintf(fileNameBuf, "%s/%s", aDir, (*dirzeiger).d_name);
		currentNode->iFileName = strdup((*dirzeiger).d_name);


    if (stat(fileNameBuf,&attribut)==-1) Log("Fehler: %s\r\n",GetLastError());
      if (S_ISDIR(attribut.st_mode))

			{
//			MessageBox("Found dir:");
//			MessageBox(fileNameBuf);

			if (aRecursive)
				{
				currentNode->iFileType = 0x1;
				ReadDir(fileNameBuf, currentNode, true);
				}
			else
				{
				currentNode->iFileType = 0x3;
				}
			}
		else
			{
//  	  MessageBox("Found file:");
   			Log("File Found: %s\r\n",fileNameBuf);

			currentNode->iFileType = 0x2;
			}

		}

	// if the last node was a child, make it an only child
	if (currentNode->iNodeType == 0x1)
		currentNode->iNodeType = 0x2;
	// if the last node was a sibling, make it the last sibling
	if (currentNode->iNodeType == 0x3)
		currentNode->iNodeType = 0x4;

	closedir(dir);
	}

// Looks for xmms, starting it if necessary. Returns whether
// xmms is running now

bool CBemusedServerDlg::CheckWinamp(const char* aWindowName)
	{
	
	if (!xmms_remote_is_running(0) && startAutomatically)
		{
		 if (!fork()) {
      system(winampPath);
      exit(0);
      }
     sleep(2);
		}

	if (xmms_remote_is_running(0))
		return true;

	return false;
	}

void CBemusedServerDlg::FadeOut()
	{
	int curVol = xmms_remote_get_main_volume(0);
	int deltaVol = curVol / 10;  // 10*0.5s = 5 seconds
	Log("curVol=%i\n",curVol);
	for(int v=curVol;v>0;v-=deltaVol) 
		{
		Log("Set volume to %i%\n",v);
		xmms_remote_set_main_volume(0,v);
		usleep(500000); // 0.5 seconds
		}
	xmms_remote_set_main_volume(0,0);
	Log("Set volume to %i%\n",0);
	usleep(500000);
	Stop(true);
	sleep(1); // Give time for Stop
	Log("Resetting volume to %i%\n",curVol);
	xmms_remote_set_main_volume(0,curVol);
	}

	
void CBemusedServerDlg::WriteDetailedInfoToPhone()
	{
	// Our variables
	int bitrate = 0;
	int samplerate = 0;
	int nochannels = 0;
	int i;
	char buffer[1024];

	// Get _current_ bit rate, sample rate and number of channels
        xmms_remote_get_info(0, &bitrate, &samplerate, &nochannels);

	// bps => kbps and Hz => kHz
	bitrate /= 1024;
	samplerate /= 1000;

 	Log("Got the song info, %d kbps, %d kHz, %d channels\n",
			bitrate,samplerate,nochannels);

	// Stuff this lot into buffer
	strcpy(buffer, "DINFACK");

	// Anyone think we ought to have a macro for this stuff?
	buffer[7] = bitrate >> 24;
	buffer[8] = (bitrate >> 16) & 0xFF;
	buffer[9] = (bitrate >> 8) & 0xFF;
	buffer[10] = bitrate & 0xFF;
	
	buffer[11] = samplerate >> 24;
	buffer[12] = (samplerate >> 16) & 0xFF;
	buffer[13] = (samplerate >> 8) & 0xFF;
	buffer[14] = samplerate & 0xFF;

	buffer[15] = nochannels >> 24;
	buffer[16] = (nochannels >> 16) & 0xFF;
	buffer[17] = (nochannels >> 8) & 0xFF;
	buffer[18] = nochannels & 0xFF;

	buffer[19] = '\0';

	unsigned long bytesWritten;

	WriteFile(iCommHandle, buffer, (19), &bytesWritten, NULL);
	if (bytesWritten < 19)
		Log("Only wrote %d bytes of DINFACK\r\n", bytesWritten);

	Log("Sent the Track Info to the phone\n");

	}

void CBemusedServerDlg::WriteInfoToPhone()
	{
  	// Get the length of the song.
	int songLength;
	int count = 0;
	usleep(100000);
	do 
		{
		songLength = xmms_remote_get_playlist_time(0,xmms_remote_get_playlist_pos(0));
		usleep(50);
		count++;
		} while ((songLength == -1) && (count < 100));
	
	if(songLength<0) songLength=0;
	songLength/=1000;

	unsigned char isPlaying=0x0;
	if (xmms_remote_is_playing(0)) isPlaying=0x1;
	if (xmms_remote_is_paused(0)) isPlaying=0x2;


	int currentTime = xmms_remote_get_output_time(0);
	iStopNow = (iStopEnd && currentTime<lastTime);
	lastTime = currentTime; 

	// current time is in milliseconds, we want seconds.
	currentTime /= 1000;

	unsigned char repeat,shuffle;
	if (xmms_remote_is_repeat(0)) repeat=0x01; else repeat=0x00;
	if (xmms_remote_is_shuffle(0)) shuffle=0x01; else shuffle=0x00;

  
	char buffer[1024];
	char title[255];
	unsigned int titlelength;

	if(songLength) 
		{
		strcpy(title,xmms_remote_get_playlist_title(0,xmms_remote_get_playlist_pos(0)));
		titlelength = strlen(title);
		} 
	else 
		{
		title[0]='\0';
		titlelength=0;
  		}
  
	strcpy(buffer, "INFOACK");
	buffer[7] = isPlaying;

	buffer[8] = songLength >> 24;
	buffer[9] = (songLength >> 16) & 0xFF;
	buffer[10] = (songLength >> 8) & 0xFF;
	buffer[11] = songLength & 0xFF;

	buffer[12] = currentTime >> 24;
	buffer[13] = (currentTime >> 16) & 0xFF;
	buffer[14] = (currentTime >> 8) & 0xFF;
	buffer[15] = currentTime & 0xFF;

	buffer[16] = shuffle;
	buffer[17] = repeat;
	strcpy(buffer+18,title);
  
	unsigned long bytesWritten;

	WriteFile(iCommHandle, buffer, (18+titlelength), &bytesWritten, NULL);
	if (bytesWritten < (18+titlelength))
		Log("Only wrote %d bytes of INFOACK\r\n", bytesWritten);
	if(iStopEnd && iStopNow) 
		{
			Stop(true);
			iStopEnd = iStopNow = false;
		}
	}

void CBemusedServerDlg::WriteInf2ToPhone()
	{
  	// Get the length of the song.
	int songLength;
	int count = 0;
	do 
		{
		songLength = xmms_remote_get_playlist_time(0,xmms_remote_get_playlist_pos(0));
		usleep(50);
		count++;
		} while ((songLength == -1) && (count < 100));
	
	if(songLength<0) songLength=0;
	songLength/=1000;

	unsigned char isPlaying=0x0;
	if (xmms_remote_is_playing(0)) isPlaying=0x1;
	if (xmms_remote_is_paused(0)) isPlaying=0x2;


	int currentTime = xmms_remote_get_output_time(0);
	iStopNow = (iStopEnd && currentTime<lastTime);
	lastTime = currentTime; 

	// current time is in milliseconds, we want seconds.
	currentTime /= 1000;

	unsigned char repeat,shuffle;
	if (xmms_remote_is_repeat(0)) repeat=0x01; else repeat=0x00;
	if (xmms_remote_is_shuffle(0)) shuffle=0x01; else shuffle=0x00;

  
	char buffer[1024];
	char title[255];
	unsigned int titlelength;
	memset(buffer, 0, sizeof(buffer));
	if(songLength) 
		{
		strcpy(title,xmms_remote_get_playlist_title(0,xmms_remote_get_playlist_pos(0)));
		titlelength = strlen(title);
		} 
	else 
		{
		title[0]='\0';
		titlelength=0;
  		}
  
	strcpy(buffer, "INF2ACK");
	buffer[7] = isPlaying;

	buffer[8] = songLength >> 24;
	buffer[9] = (songLength >> 16) & 0xFF;
	buffer[10] = (songLength >> 8) & 0xFF;
	buffer[11] = songLength & 0xFF;

	buffer[12] = currentTime >> 24;
	buffer[13] = (currentTime >> 16) & 0xFF;
	buffer[14] = (currentTime >> 8) & 0xFF;
	buffer[15] = currentTime & 0xFF;

	buffer[16] = shuffle;
	buffer[17] = repeat;
	strcpy(buffer+18,title);
  
	unsigned long bytesWritten;

	WriteFile(iCommHandle, buffer, (19+titlelength), &bytesWritten, NULL);
	if (bytesWritten < (19+titlelength))
		Log("Only wrote %d bytes of INF2ACK\r\n", bytesWritten);
	if(iStopEnd && iStopNow) 
		{
			Stop(true);
			iStopEnd = iStopNow = false;
		}
	}
	
void CBemusedServerDlg::SetSeek()
	{
	unsigned long bytesRead = 0;
	unsigned char indexBytes[4];
	int seek = 0;

	if (!ReadFile(iCommHandle, indexBytes, 4,&bytesRead, NULL))
		{
		Log("Couldn't read seek: %d\r\n", GetLastError());
		return;
		}

	seek = (indexBytes[0] << 24) + (indexBytes[1] << 16) +
		   (indexBytes[2] << 8) + indexBytes[3];

	xmms_remote_jump_to_time(0,seek*1000);

	Log("Set seek to %d seconds\r\n", seek);
	}

void CBemusedServerDlg::GetVolume()
{
	unsigned char cVol=(unsigned 
	char)((xmms_remote_get_main_volume(0)*256)/100);
	char buffer[8];
	
	strcpy(buffer, "GVOLACK");
	buffer[7]=cVol;
	
	unsigned long bytesWritten;
	WriteFile(iCommHandle, buffer, 8, &bytesWritten, NULL);
	Log("Send Volume\r\n");
	
}

void CBemusedServerDlg::Version()
{
	char buffer[9];
	strcpy(buffer, "VERSACK");
	buffer[7]=char(1);
	buffer[8]=char(73);
	unsigned long bytesWritten;
	WriteFile(iCommHandle, buffer, 9, &bytesWritten, NULL);
	Log("Send Version Info\r\n");
	
}

void CBemusedServerDlg::RemoveAllFromPlaylist()
	{
	// WARNING:
	//	Can cause issues with some XMMS versions
	xmms_remote_stop(0);
	xmms_remote_playlist_clear(0);
	Log("Removed all songs from playlist\n");
	}

void CBemusedServerDlg::SelectInPlaylist()
	{
	unsigned char indexBytes[2];
	unsigned long bytesRead = 0;
	int pos;

	if (!ReadFile(iCommHandle, indexBytes, 2, &bytesRead, NULL))
		{
		Log("Couldn't read playlist selection: %d\r\n", GetLastError());
		return;
		}

	pos = (indexBytes[0] << 8) + indexBytes[1];
	xmms_remote_set_playlist_pos(0, pos);
	Log("Setting playlist position to %d\n",pos);
	
	}


void CBemusedServerDlg::PlayFile(bool aAddToPlaylist)
	{
	unsigned long bytes = 0;

	unsigned char ubuffer[10];
	char buffer[1024];
	int filenameLength = 0;
	memset(buffer, 0, sizeof(buffer));

//	MessageBox("PLAY");

	if (!ReadFile(iCommHandle, ubuffer, 2, &bytes, NULL))

		{
		Log("Couldn't read filename length: %d\r\n", GetLastError());
		return;
		}

	filenameLength = (ubuffer[0] << 8) + ubuffer[1];

	if (!ReadFile(iCommHandle, buffer, filenameLength, &bytes, NULL))
		{
		Log("Couldn't read filename of length %d: %d\r\n", filenameLength, GetLastError());
		return;
		}
  for (int i=0; i<filenameLength;i++)  if (buffer[i]=='\\') buffer[i]='/';

  // Build up bookpath directory, depending on multiple dirs or not
  if (!strchr(mp3Dirs, ';')) 
     {
	// is base path + magic path
	strcpy(wbookpath,mp3Dirs);
	strcat(wbookpath,"/");
	strcat(wbookpath,bookpath);
     }
  else
     {
	// Is just the magic path
	strcpy(wbookpath,bookpath);
     }
  Log("wbookpath is \"%s\"\n",wbookpath);

  // Bookmarks Check
  if (!strncmp(buffer,wbookpath,strlen(wbookpath)-1))
    {
       char t[1000];
       strcpy(t,&buffer[strlen(wbookpath)]);
       Log("Found bookmark entry %s\n",t);
       
       bool found = false;
       for (int i=0;i<nobookmarks;i++)
	  {
	     if(!strcmp(t,bookmarktitles[i]))
	       {
		  found = true;
		  strcpy(buffer,bookmarks[i]);
	       }
	  }
       if (!found)
	  {
              Log("Error! Unable to find bookmark for title \"%s\"!\n",t);
	      return;
	  }
    }
  Log("About to play file \"%s\"\n",buffer);


	// clear the playlist if required
	if (!aAddToPlaylist)
	  xmms_remote_playlist_clear(0);

  // add this song to the playlist

  GList *list = 0;
  list = g_list_append(list, g_strdup((gchar *)(buffer)));
  xmms_remote_playlist_add(0,list);
  g_list_free(list);
	// start playing!
	if (!aAddToPlaylist)
		{
		Log("Playing \"%s\"\r\n", buffer);
		xmms_remote_play(0);
		}
	else
		{
		Log("Added \"%s\" to playlist\r\n", buffer);
		return;
		}

	int songLength;
	int count = 0;

	do {
		songLength = xmms_remote_get_playlist_time(0,xmms_remote_get_playlist_pos(0));
		usleep(800);
		count++;
		} while ((songLength == -1) && (count < 100));

	}

void CBemusedServerDlg::GetFileInfo()
	{
	unsigned long bytes = 0;

	unsigned char buffer[1024];
	int filenameLength = 0;
	memset(buffer, 0, sizeof(buffer));

	if (!ReadFile(iCommHandle, buffer, 2, &bytes, NULL))
		{
		Log("Couldn't read filename length: %d\r\n", GetLastError());
		return;
		}

	filenameLength = (buffer[0] << 8) + buffer[1];
	buffer[0] = '\0';
	buffer[1] = '\0';

	if (!ReadFile(iCommHandle, buffer, filenameLength, &bytes, NULL))
		{
		Log("Couldn't read filename: %d\r\n", GetLastError());
		return;
		}

  for (int i=0; i<filenameLength;i++)  if (buffer[i]=='\\') buffer[i]='/';

	Log("Returning info about \"%s\": ", buffer);

	FILE* file = fopen((char*) buffer, "rb");

	if (file)
		{
		fseek(file, 0, SEEK_END);
		long fileLength = ftell(file);
		fseek(file, 0, SEEK_SET);
		fclose(file);
		Log("length is %d\r\n", fileLength);

		char ackBuf[11];
		strcpy(ackBuf, "FINFACK");
		ackBuf[7] = (fileLength >> 24) & 0xFF;
		ackBuf[8] = (fileLength >> 16) & 0xFF;
		ackBuf[9] = (fileLength >> 8) & 0xFF;
		ackBuf[10] = fileLength & 0xFF;

		WriteFile(iCommHandle, ackBuf, 11, &bytes, NULL);
		}
	else
		{
		Log("couldn't open file\r\n");
		}

	}


void CBemusedServerDlg::DownloadFile()
	{
	unsigned long bytes = 0;

	unsigned char buffer[1024];
	int filenameLength = 0;
	memset(buffer, 0, sizeof(buffer));

	if (!ReadFile(iCommHandle, buffer, 2, &bytes, NULL))
		{
		Log("Couldn't read filename length: %d\r\n", GetLastError());
		return;
		}

	filenameLength = (buffer[0] << 8) + buffer[1];
	buffer[0] = '\0';
	buffer[1] = '\0';

	if (!ReadFile(iCommHandle, buffer, filenameLength, &bytes, NULL))
		{
		Log("Couldn't read filename: %d\r\n", GetLastError());
		return;
		}
  for (int i=0; i<filenameLength;i++)  if (buffer[i]=='\\') buffer[i]='/';

	Log("Uploading \"%s\"... ", buffer);

	FILE* file = fopen((char*) buffer, "rb");
	unsigned long bytesRead;

	if (file)
		{
		char ackBuf[8];
		strcpy(ackBuf, "DOWNACK");
		WriteFile(iCommHandle, ackBuf, 7, &bytes, NULL);

		do {
			bytesRead = fread(buffer, 1, sizeof(buffer), file);

			if (bytesRead > 0)
				{
				WriteFile(iCommHandle, buffer, bytesRead, &bytes, NULL);
//				if (bytes < bytesRead)
//					Log("wrote %d bytes of %d read from file\r\n", bytes, bytesRead);
				}
			} while (bytesRead > 0);

		Log("finished\r\n");
		}
	else
		{
		Log("couldn't open file\r\n");
		}

	fclose(file);
	}

void CBemusedServerDlg::SetVolume()
	{
	unsigned long bytesRead = 0;
	unsigned char volume = 0;

	if (!ReadFile(iCommHandle, &volume, 1, &bytesRead, NULL))
		{
		Log("Couldn't read volume: %d\r\n", GetLastError());
		return;
		}

	// set the volume

  xmms_remote_set_main_volume(0,(volume*100)/255);

	Log("Set volume to %d%%\r\n", (volume * 100) / 255);
	}

void CBemusedServerDlg::Play()
{
	if (xmms_remote_get_playlist_length(0)) // to prevent open file dialog opening
	{
		xmms_remote_play(0);
		Log("Playing\r\n");
	}
	else
	{
		Log("Received PLAY, but there is nothing to play\r\n");
	}
}

void CBemusedServerDlg::Stop(bool aFadeOut)
	{
	if (aFadeOut)
    	xmms_remote_stop(0);
	else
		xmms_remote_stop(0);

	Log("Stopping\r\n");
	}

void CBemusedServerDlg::Pause()
	{
	xmms_remote_pause(0);
	Log("Pause\r\n");
	}

void CBemusedServerDlg::NextTrack()
	{
	xmms_remote_playlist_next(0);
	Log("Next track\r\n");

	int songLength;
	int count = 0;

	do {
		songLength = xmms_remote_get_playlist_time(0,xmms_remote_get_playlist_pos(0));

		usleep(50);
		count++;
		} while ((songLength == -1) && (count < 100));
	}

void CBemusedServerDlg::PreviousTrack()
	{
	xmms_remote_playlist_prev(0);
	Log("Previous track\r\n");

  int songLength;
	int count = 0;

	do {
		songLength = xmms_remote_get_playlist_time(0,xmms_remote_get_playlist_pos(0));
		usleep(50);
		count++;
		} while ((songLength == -1) && (count < 100));
	}

void CBemusedServerDlg::FastForward()
	{
	int atime=xmms_remote_get_output_time(0);
	xmms_remote_jump_to_time(0,atime+fastforbackspeed);
	Log("Fast forward\r\n");
	}

void CBemusedServerDlg::Check()
	{
	unsigned long bytesWritten;
	char check[]="Y";
	WriteFile(iCommHandle, check, 1, &bytesWritten, NULL);
	}


void CBemusedServerDlg::Rewind()
	{
	int atime=xmms_remote_get_output_time(0);
	atime-=fastforbackspeed;
	if (atime<0) atime=0;
	xmms_remote_jump_to_time(0,atime);
	Log("Rewind\r\n");
	}


void CBemusedServerDlg::Shuffle()
	{
	unsigned long bytesRead = 0;
	unsigned char shuffleOn = 0;

	if (!ReadFile(iCommHandle, &shuffleOn, 1, &bytesRead, NULL))
		{
		Log("Couldn't read shuffle: %d\r\n", GetLastError());
		return;
		}

	if (shuffleOn) {
    if (!xmms_remote_is_shuffle(0)) xmms_remote_toggle_shuffle(0);
    }
  else {
    if (xmms_remote_is_shuffle(0)) xmms_remote_toggle_shuffle(0);
  }

	Log("Changing shuffle to %s\r\n", shuffleOn ? "on" : "off");
	}


void CBemusedServerDlg::Repeat()
	{
	unsigned long bytesRead = 0;
	unsigned char repeatOn = 0;

	if (!ReadFile(iCommHandle, &repeatOn, 1, &bytesRead, NULL))
		{
		Log("Couldn't read repeat: %d\r\n", GetLastError());
		return;
		}

	if (repeatOn) {
    if (!xmms_remote_is_repeat(0)) xmms_remote_toggle_repeat(0);
    }
  else {
    if (xmms_remote_is_repeat(0)) xmms_remote_toggle_repeat(0);
  }

	Log("Changing repeat to %s\r\n", repeatOn ? "on" : "off");
	}

void CBemusedServerDlg::ShutDown()
	{
	Log("Shutting down Linux (only, if you have the right to do so)\r\n");
  system("/sbin/shutdown -h now");
	}

void CBemusedServerDlg::ResetWrittenFlag(CDirTreeNode* aNode)
	{
	aNode->iWrittenToBuffer = false;

	if (aNode->iFirstChild)
		ResetWrittenFlag(aNode->iFirstChild);
	if (aNode->iNextSibling)
		ResetWrittenFlag(aNode->iNextSibling);
	}



void CBemusedServerDlg::WriteListToPhone()
	{
	unsigned long bytesWritten = 0;
	unsigned char buffer[1024];
	unsigned char* bufferPtr;

	// Get a list of the files we can browse.
	char pathBuffer[256];

  strcpy((char*)pathBuffer,mp3Dirs);
	if ((strlen(pathBuffer) > 0) && (pathBuffer[strlen(pathBuffer)-1] == '/'))
	pathBuffer[strlen(pathBuffer)-1] = '\0';


	GenerateFileList(pathBuffer, true);

	WriteFile(iCommHandle, "LISTACK", 7, &bytesWritten, NULL);
	if (bytesWritten < 7)
		{
		Log("Couldn't write list to phone (error %d)\r\n", GetLastError());
		return;
		}

	int sizeLeft;
	int nextPos;
	bool allDone;

	int totalBytesWritten = 0;

	// If we don't have any files, just return end-of-list.
	if (!iDirTreeRoot)
		{
		buffer[0] = 0xFF;
		buffer[1] = 0x00;
		WriteFile(iCommHandle, buffer, 2, &bytesWritten, NULL);
		return;
		}

	iDirTreeCurrentNode = iDirTreeRoot;
	ResetWrittenFlag(iDirTreeRoot);

	do {
		sizeLeft = sizeof(buffer) - 2;

		bufferPtr = buffer;
		memset(buffer, 0, sizeof(buffer));
		allDone = WriteNodeToBuffer(iDirTreeRoot, bufferPtr, sizeLeft);

		totalBytesWritten += (sizeof(buffer) - sizeLeft);
		nextPos = sizeof(buffer) - 2 - sizeLeft;

		if (allDone)
			{
			// Write "last entry" token.
			buffer[nextPos++] = 0xFF;
			buffer[nextPos++] = 0x00;
			}

		bytesWritten = 0;
		WriteFile(iCommHandle, buffer, nextPos, &bytesWritten, NULL);
		if (bytesWritten < (unsigned long) nextPos)
			{
			Log("Couldn't write list to phone (error %d)\r\n", GetLastError());
			return;
			}
		} while (!allDone);

	Log("Wrote song list to phone (%d bytes)\r\n", totalBytesWritten);
	}


void CBemusedServerDlg::WritePlaylistToPhone()
	{
	unsigned long bytesWritten = 0;
	char buffer[1024];
	char eol[2];
	int i;
	int towrite = 0;
	int noentries = 0;
	int playlistpos;

	eol[0] = '\n';
	eol[1] = '\0';

	// Fetch details
	playlistpos = xmms_remote_get_playlist_pos(0);
	noentries = xmms_remote_get_playlist_length(0);

	// Stuff this lot into buffer
	strcpy(buffer, "PLSTACK");
        buffer[7] = (playlistpos >> 8) & 0xFF;
        buffer[8] = playlistpos & 0xFF;

	buffer[9] = '#';
	buffer[10] = '\n'; // need some junk and a \n after the size
			   // winamp achieves this with the m3u header
	towrite = 11;

	// Send this bit on it's way
	WriteFile(iCommHandle, buffer, towrite, &bytesWritten, NULL);
	if (bytesWritten < towrite)
		Log("Only wrote %d bytes of PLSTACK\r\n", bytesWritten);

	// Now pull down and send the playlist
	for(i=0;i<noentries;i++) {
		sprintf(buffer,xmms_remote_get_playlist_title(0,i));
		Log("Track Title is \"%s\"\n",buffer);
		strcat(buffer,eol); // add \n
		towrite=strlen(buffer);

		WriteFile(iCommHandle, buffer, towrite, &bytesWritten, NULL);
		if (bytesWritten < towrite)
			Log("Only wrote %d bytes of PLSTACK\r\n", bytesWritten);
	}

	// Send the end
	buffer[0] = '\0';
	WriteFile(iCommHandle, buffer, 1, &bytesWritten, NULL);
	
	Log("Sent the playlist to the phone, %d entries, position is %d\n",
			noentries,playlistpos);

	}


void CBemusedServerDlg::WriteDirectoryListToPhone()
	{
	unsigned long bytesWritten = 0;
	unsigned char buffer[1024];
	unsigned char* bufferPtr;

	int filenameLength = 0;
	unsigned long bytes;
	memset(buffer, 0, sizeof(buffer));

	if (!ReadFile(iCommHandle, buffer, 2, &bytes, NULL))
		{
		Log("Couldn't read directory name length: %d\r\n", GetLastError());
		return;
		}

	filenameLength = (buffer[0] << 8) + buffer[1];
	buffer[0] = '\0';
	buffer[1] = '\0';
	
	
	if ((filenameLength!=0) && (!ReadFile(iCommHandle, buffer, filenameLength, &bytes, NULL)))
		{
		Log("Couldn't read directory name: %d\r\n", GetLastError());
		return;
		}
		
		
		
	for (int i=0; i<filenameLength;i++)
	{
		if (buffer[i]=='\\') buffer[i]='/';	
	}
	
	if (!strcmp((char*)buffer, ""))
		{
		strcpy((char*)buffer,mp3Dirs);
		if ((strlen((char*)buffer) > 0) && (buffer[strlen((char*)buffer)-1] == '/'))
		buffer[strlen((char*)buffer)-1] = '\0';
		}
	
	//buffer[filenameLength]='/';
		
	char brot[1024];
	strcpy((char*)brot,(char*)buffer);
	brot[filenameLength]='\0';
	
	Log("brot: %s\r\n",brot);
	Log("Listing \"%s\": ", buffer);

	GenerateFileList((char*)buffer, false);

	// Note that we return a standard LISTACK to simplify client-side handling.
	WriteFile(iCommHandle, "LISTACK", 7, &bytesWritten, NULL);
	if (bytesWritten < 7)
		{
		Log("Couldn't write list to phone (error %d)\r\n", GetLastError());
		return;
		}

	int sizeLeft;
	int nextPos;
	bool allDone;

	int totalBytesWritten = 0;

	// If we don't have any files, just return end-of-list.
	if (!iDirTreeRoot)
		{
		buffer[0] = 0xFF;
		buffer[1] = 0x00;
		WriteFile(iCommHandle, buffer, 2, &bytesWritten, NULL);

		Log("no files to list\r\n");
		return;
		}

	iDirTreeCurrentNode = iDirTreeRoot;
	ResetWrittenFlag(iDirTreeRoot);

	do {
		sizeLeft = sizeof(buffer) - 2;

		bufferPtr = buffer;
		memset(buffer, 0, sizeof(buffer));
		allDone = WriteNodeToBuffer(iDirTreeRoot, bufferPtr, sizeLeft);

		totalBytesWritten += (sizeof(buffer) - sizeLeft);
		nextPos = sizeof(buffer) - 2 - sizeLeft;

		if (allDone)
			{
			// Write "last entry" token.
			buffer[nextPos++] = 0xFF;
			buffer[nextPos++] = 0x00;
			}

		bytesWritten = 0;
  	WriteFile(iCommHandle, buffer, nextPos, &bytesWritten, NULL);
		if (bytesWritten < (unsigned long) nextPos)
			{
			Log("Couldn't write list to phone (error %d)\r\n", GetLastError());
			return;
			}
		} while (!allDone);

	Log("wrote list to phone (%d bytes)\r\n", totalBytesWritten);
	}




bool CBemusedServerDlg::WriteNodeToBuffer(CDirTreeNode* aNode, unsigned char*& aBufferPtr, int& aSizeRemaining)
	{
	int lengthNeeded = strlen(aNode->iFileName) + 2;
	if (aSizeRemaining < lengthNeeded)
		return false;

	unsigned char type = (aNode->iNodeType << 4) + aNode->iFileType;

	if (!aNode->iWrittenToBuffer)
		{
		aBufferPtr[0] = type;
		memcpy(&aBufferPtr[1], aNode->iFileName, lengthNeeded - 1);

		aBufferPtr += lengthNeeded;
		aSizeRemaining -= lengthNeeded;

		aNode->iWrittenToBuffer = true;
		}

	int ret = true;

	if (ret && aNode->iFirstChild)
		{
//		iDirTreeCurrentNode = aNode->iFirstChild;
		ret = WriteNodeToBuffer(aNode->iFirstChild, aBufferPtr, aSizeRemaining);
		}

	if (ret)
		{
		if (aNode->iNextSibling)
			{
//			iDirTreeCurrentNode = aNode->iNextSibling;
			ret = WriteNodeToBuffer(aNode->iNextSibling, aBufferPtr, aSizeRemaining);
			}
//		else
//			{
//			if (aNode->iParent && aNode->iParent->iNextSibling)
//				{
//				iDirTreeCurrentNode = aNode->iParent->iNextSibling;
//				ret = WriteNodeToBuffer(iDirTreeCurrentNode, aBufferPtr, aSizeRemaining);
//				}
//			}
		}

//	if (aNode->iFirstChild)
//		iDirTreeCurrentNode = aNode->iFirstChild;

	return ret;
	}




void CBemusedServerDlg::GenerateFileList(const char* aRoot, bool aRecursive)
	{
  delete iDirTreeRoot;
	iDirTreeRoot = NULL;

	if (!strcmp(aRoot, ""))
		return;

	iDirTreeRoot = new CDirTreeNode;
	iDirTreeRoot->iFileType = 0x1; // dir
	iDirTreeRoot->iNodeType = 0x0; // root
	iDirTreeRoot->iFirstChild = iDirTreeRoot->iNextSibling = NULL;
	iDirTreeCurrentNode = iDirTreeRoot;

	// Different handling here based on whether we've only got one directory as our root,
	// or multiple directories.
	if (strchr(aRoot, ';'))
		{
		iDirTreeRoot->iFileName = strdup("");

		char rootPath[1024];
		const char* rootPtr = aRoot;
		CDirTreeNode* newNode;
		CDirTreeNode* lastNewNode;
		int pathCount = 0;
		bool onLastPath = false;

		while (1)
			{
			memset(rootPath, 0, sizeof(rootPath));

			if (!onLastPath)
				{
				strncpy(rootPath, rootPtr, strchr(rootPtr, ';') - rootPtr);
				rootPtr = strchr(rootPtr, ';') + 1;
				}
			else
				{
				strcpy(rootPath, rootPtr);
				}

			// Remove a trailing backslash if there is one.
			if ((strlen(rootPath) > 0) && (rootPath[strlen(rootPath)-1] == '/'))
				rootPath[strlen(rootPath)-1] = '\0';

			// Check that we've got a valid path.
			if (!strcmp(rootPath, ""))
				{
				if (!strchr(rootPtr, ';'))
					onLastPath = true;
				continue;
				}

			pathCount++;

			newNode = new CDirTreeNode;
			newNode->iParent = iDirTreeRoot;
			newNode->iFileName = strdup(rootPath);

			if (aRecursive)
				newNode->iFileType = 0x1; // dir
			else
				newNode->iFileType = 0x3; // unexpanded dir

			if (pathCount == 1)
				{
				iDirTreeRoot->iFirstChild = newNode;
				newNode->iNodeType = 0x1; // child
				}
			else
				{
				lastNewNode->iNextSibling = newNode;
				newNode->iNodeType = 0x3; // sibling
				}

			iDirTreeCurrentNode = newNode;

			if (aRecursive)
				ReadDir(newNode->iFileName, newNode, aRecursive);

			lastNewNode = newNode;

			if (onLastPath)
				break;

			if (!strchr(rootPtr, ';'))
				onLastPath = true;
			}

		// Bookmarks
		if(nobookmarks > 0)
		   {
			AddBookmarks(newNode, iDirTreeRoot, aRecursive);
		   }
		else
		   if (newNode)
			newNode->iNodeType = 0x4; // last sibling
		}
	else
		{
		iDirTreeRoot->iFileName = strdup(aRoot);

		ReadDir(iDirTreeRoot->iFileName, iDirTreeRoot, aRecursive);
		// Bookmarks
		if(nobookmarks > 0)
		   {

		        CDirTreeNode* nNode = iDirTreeRoot->iFirstChild;
			if(nNode->iNodeType == 0x1)
			   {
				nNode = nNode->iFirstChild;
			   }

			if(nNode->iNodeType == 0x2 || nNode->iNodeType == 0x1)
			   {
				   Log("Only child node\n");
			       AddBookmarks(nNode, iDirTreeRoot, aRecursive);
			   }
			else
			   {
			      while(nNode->iNodeType == 0x3)
			         {
			 		Log("Skipping sibling\n");
				     nNode = nNode->iNextSibling;
			         }
			      AddBookmarks(nNode, iDirTreeRoot, aRecursive);
			   }
		   }
		}
	}



void CBemusedServerDlg::AddBookmarks(CDirTreeNode* aNode, CDirTreeNode* pNode, bool aRecursive)
	{

	CDirTreeNode* newNode;
	CDirTreeNode* lastNewNode;

	// aNode is the one we should add after, if any
        if (aNode) 
           {
        	aNode->iNextSibling = new CDirTreeNode;
		aNode->iNodeType=0x3; // Sibling
		newNode = aNode->iNextSibling;
		newNode->iNodeType=0x4; // Last Sibling
           }
	else
	   {
		newNode = new CDirTreeNode;
	        newNode->iNodeType=0x2; // Only Child
		pNode->iFirstChild = newNode;
	   }

	newNode->iParent = pNode;

	// Remove the trailing / from bookpath, then send
	strcpy(wbookpath,bookpath);
	wbookpath[strlen(bookpath)-1]='\0';
	Log("Bookmarks in \"%s\" \"%s\"\n",wbookpath,bookpath);

        newNode->iFileName = wbookpath;

	if (aRecursive)
	   {
		newNode->iFileType = 0x1;
                lastNewNode = newNode;
		newNode = NULL;

		// Bookmark 1
		newNode = new CDirTreeNode;
		newNode->iParent = lastNewNode;
		newNode->iNodeType=0x1;
		newNode->iFileType=0x2;
		newNode->iFileName=bookmarktitles[0];
		lastNewNode->iFirstChild=newNode;

		// Rest
		for(int i=1;i<nobookmarks;i++)
		    {
			newNode->iNextSibling = new CDirTreeNode;
			newNode = newNode->iNextSibling;
			newNode->iParent = lastNewNode;
			newNode->iNodeType=0x3;
			newNode->iFileType=0x2;
			newNode->iFileName=bookmarktitles[i];
		    }

		if(nobookmarks==1)
		        newNode->iNodeType=0x2;
		else
		        newNode->iNodeType=0x4;

	   }
	else
	   {
	        newNode->iNodeType=0x2;
		newNode->iFileType = 0x3;
	   }
	}


int CBemusedServerDlg::BluetoothConnectToSocket(int channel)
	{
   int s=0;

#ifndef AFFIX
    struct sockaddr_rc loc_addr;
#else
   struct sockaddr_affix loc_addr;
   int err;
#endif

struct sockaddr_in iploc_addr;

#ifdef AFFIX
	if (!tcp) {
	  err = sdpreg_init();
	  if (err < 0) {
		 Log("Can not listen on the socket. %s\r\n", strerror(errno));
	      	 exit(1);
		 Log("sdpreg init\n");
	  }
	}
#endif

	int pf;
	int proto;

#ifndef AFFIX
	pf=PF_BLUETOOTH;
#else
	pf=PF_AFFIX;
#endif
	proto=BTPROTO_RFCOMM;

	if (tcp) {
	  pf=PF_INET;
	  proto=IPPROTO_TCP;
	}

	if( (s = socket(pf, SOCK_STREAM, proto)) < 0 ) {
		Log("Can't create socket. %s\r\n", strerror(errno));
		exit(1);
	}

#ifndef AFFIX
	 loc_addr.rc_family = AF_BLUETOOTH;
	 loc_addr.rc_bdaddr = bdaddr;
	 loc_addr.rc_channel = uint8_t(channel);
	 if (!tcp)
	 {
	   char tmpstring[50];
	   sprintf(tmpstring, "sdptool add --channel=%i SP", channel);
	   system(tmpstring);
	   Log("registered SP for channel %i\r\n", channel);
	 }
#else
	 loc_addr.family = AF_AFFIX;
	 loc_addr.bda = bdaddr;
	 loc_addr.port = channel;
#endif
	 if (tcp) {
	   iploc_addr.sin_family = AF_INET;
	   iploc_addr.sin_port = htons(tcpport);
	   struct in_addr lokaleip;
	   lokaleip.s_addr=INADDR_ANY;
	   iploc_addr.sin_addr = lokaleip;
	 }
	 struct sockaddr* socketaddr=(struct sockaddr *)&loc_addr;
	 if (tcp) socketaddr=(struct sockaddr *)&iploc_addr;

	 if( bind(s, socketaddr, sizeof(*socketaddr)) < 0 ) {
		 Log("Can't bind socket. %s, %f\r\n", strerror(errno),float(s));
		 exit(1);
	 }

	 if( listen(s, 10) ) {
		 Log("Can not listen on the socket. %s\r\n", strerror(errno));

		 exit(1);
	 }

#ifdef AFFIX
	if (!tcp) {
	   err = sdpreg_serialport(channel);
	   if (err < 0) {
    		 Log("Can not listen on the socket. %s\r\n", strerror(errno));
		 exit(1);
	   }
	   Log("reg ser port\n");
	}
#endif
  return s;

	}


int CBemusedServerDlg::BluetoothWaitforConnect(int s)
  {
   int s1=0,opt;
#ifndef AFFIX
   bdaddr_t ba;
   struct sockaddr_rc rem_addr;
#else
   BD_ADDR ba;
   struct sockaddr_affix   rem_addr;
#endif
   struct sockaddr_in iprem_addr;

   if (!tcp) Log("Waiting for connection over bluetooth\r\n"); else
   	     Log("Waiting for conection over TCP/IP (Port: %i)\r\n",tcpport);

   struct sockaddr* socketaddr=(struct sockaddr *)&rem_addr;
   if (!tcp)
   {
   	opt = sizeof(rem_addr);
   }
   else
   {
	opt = sizeof(iprem_addr);
	socketaddr=(struct sockaddr *)&iprem_addr;
   }
	 if( (s1 = accept(s, socketaddr, (socklen_t *)&opt)) < 0 )
	 {
			Log("Accept failed. %s\r\n", strerror(errno));
			exit(1);
   	 }

   if (!tcp)
   {
#ifndef AFFIX
   	baswap(&ba, &rem_addr.rc_bdaddr);
#else
   	baswap(&ba, &rem_addr.bda);
#endif
   	Log("Connect from %s\r\n", batostr(&ba));
   }
   else
   {
	Log("Connect from %s\r\n", inet_ntoa(iprem_addr.sin_addr));
   }


   return s1;
  }


void CBemusedServerDlg::Log(char* aFormatString, ...)
	{
  char logBuffer[1024];
  va_list argList;
	va_start(argList, aFormatString);
	vsprintf(logBuffer, aFormatString, argList);
	va_end(argList);
	cout << logBuffer;
	}


char* CBemusedServerDlg::GetLastError()
  {
  return strerror(errno);
  }
