/*
 * surfer.c: A plugin for the Video Disk Recorder
 *
 * See the README file for copyright information and how to reach the author.
 *
 * $Id$
 */

/*
 * todo:
 *   - #defines für Arraygrössen
 *   - link-base prüfen (Werbung,...)
 *   - SetupMenu
 *   - Unterpage als neue Startseite
 *   - richtige Surfhistorie
 *   - i18n
 */
#include <vdr/status.h>
#include <vdr/plugin.h>
#include <vdr/osdbase.h>

static const char *VERSION        = "0.0.2";
static const char *DESCRIPTION    = "News-Surfer";
static const char *MAINMENUENTRY  = "News-Surfer";

int lynx_width = 56;
// --- cOSDSurfer ------------------------------------------------------------

class cOSDSurfer : public cOsdMenu {
private:
	// Main Bookmarks --> Config
	int bookmarkIDX, numBookmarkIDX;
	char bookmarks[10][200], bookmarkHeadings[10][200];
	// Sub-Bookmarks --> from first Page of Bookmarks
	int subBookmarkIDX, numSubBookmarkIDX;
	char subBookmarks[500][200];
	char surferdir[200], surferconfig[200];
public:
	cOSDSurfer();
	void changeURL(int number);
	virtual void Display(void);
	virtual eOSState ProcessKey(eKeys Key);
};

cOSDSurfer::cOSDSurfer() :cOsdMenu("") {
	memset(surferdir, 0, 200);
	memset(bookmarks, 0, 2000);
	memset(bookmarkHeadings, 0, 2000);
	memset(subBookmarks, 0, 100000);
	strcpy(surferdir, cPlugin::ConfigDirectory());
	strcat(surferdir, "/surfer");
	strcpy(surferconfig, surferdir);
	strcat(surferconfig, "/surfer.conf");
	bookmarkIDX = 0;
	numBookmarkIDX = 0;
	subBookmarkIDX = -1;
	numSubBookmarkIDX = 0;

	FILE *fp = fopen(surferconfig, "r");
	if(fp) {
		char c = '\0';
		while (c != EOF && numBookmarkIDX < 10) {
			int i = 0;
			char tempLine[200];
			memset(tempLine, 0, 200);
			while( (c = getc(fp)) != '\n' && c != EOF ) {
				tempLine[i++] = c;
			}
			// Format:
			// 1. Nicht Leer
			// 2. Beginnt nicht mit "#"
			// 3. HEADING#URL
			// 3a. URL
			if(strlen(tempLine) > 0) { // 1.
				char *p = strstr(tempLine, "#");
				if(p != tempLine) { // 2.
					if(p != NULL) {
						strncpy(bookmarkHeadings[numBookmarkIDX], tempLine, strlen(tempLine) - strlen(p));
						strcpy(bookmarks[numBookmarkIDX], p + 1);
					} else {
						strcpy(bookmarkHeadings[numBookmarkIDX], "Surfer");
						strcpy(bookmarks[numBookmarkIDX], tempLine);
					}
					numBookmarkIDX++;
				}
			}
		}
		fclose(fp);
	}
}

void cOSDSurfer::Display(void) {
	cOsdMenu::Display();

	// Save values ;)
	if(bookmarkIDX >= numBookmarkIDX || bookmarkIDX < 0) {
		bookmarkIDX = numBookmarkIDX - 1;
		SetStatus("Keine URL");
		return;
	}
	if(subBookmarkIDX > -1) {
		if(subBookmarkIDX >= numSubBookmarkIDX - 1 || subBookmarkIDX < -1) {
			subBookmarkIDX = numSubBookmarkIDX - 1;
			SetStatus("Keine URL");
			return;
		}
	}

	DisplayMenu()->SetTitle(bookmarkHeadings[bookmarkIDX]);
	SetStatus("Downloading..");

	char cmd[300];
	char stat[300];
	char *buffer;
	int cmd_ok = 0;
	FILE *fp = NULL;
	bool pageRead = false;

	// Download Page..
	memset(cmd, 0, 300);
	memset(stat, 0, 300);
	if(subBookmarkIDX == -1) {
		sprintf(cmd, "%s/getPage.sh \"%s\" %d %d", surferdir, bookmarks[bookmarkIDX], 1, lynx_width);
		dsyslog("downloading %s", bookmarks[bookmarkIDX]);
	} else {
		sprintf(cmd, "%s/getPage.sh \"%s\" %d %d", surferdir, subBookmarks[subBookmarkIDX], 0, lynx_width);
		dsyslog("downloading %s", subBookmarks[subBookmarkIDX]);
	}
	cmd_ok = system (cmd);

	// Read Page..
	dsyslog("Reading Page..");
	if (cmd_ok != -1)
		fp = fopen("/tmp/surfer.tmp", "r");
	if (cmd_ok != -1 && fp) {
		fseek(fp, 0, SEEK_END);
		int size = ftell(fp);

		printf("Size: %d\n", size);
		fseek(fp, 0, SEEK_SET);   

		buffer = (char *)malloc(size + 1);
		fread(buffer, 1, size, fp);
		buffer[size] = '\0';
		fclose(fp);
		pageRead = true;
	} else {
		buffer = new char[5];
		strcpy(buffer, "empty");
	}
	// Display Page..
	DisplayMenu()->SetText(buffer, 0);
	delete buffer;

	// Fill SubLinks..
	if(pageRead && subBookmarkIDX == -1) {
		dsyslog("Reading Links..");
		numSubBookmarkIDX = 0;
		memset(subBookmarks, 0, 100000);
		fp = fopen("/tmp/surfer.tmp.lnk", "r");
		if(fp) {
			char c = '\0';
			while (c != EOF && numSubBookmarkIDX < 500) {
				int i = 0;
				char tempLine[200];
				memset(tempLine, 0, 200);
				while( (c = getc(fp)) != '\n' && c != EOF ) {
					tempLine[i++] = c;
				}
				strcpy(subBookmarks[numSubBookmarkIDX++], tempLine);
			}
			fclose(fp);
		}
		sprintf(stat, "%d Links retrieved", numSubBookmarkIDX - 1);
	} else {
		sprintf(stat, "Link %d von %d", subBookmarkIDX + 1, numSubBookmarkIDX - 1);
	}

	// Displaystatus Update
	SetStatus(stat);
	if(subBookmarkIDX > -1) {
		if(subBookmarkIDX + 1 < numSubBookmarkIDX)
			SetHelp("Zurück", "Vorwärts", "", "");
		else
			SetHelp("Zurück", "", "", "");
	} else {
		if(numSubBookmarkIDX > 0)
			SetHelp("", "Vorwärts", "", "");
		else
			SetHelp("", "", "", "");
	}
}

void cOSDSurfer::changeURL(int number) {
	bookmarkIDX = number;
	subBookmarkIDX = -1;
	numSubBookmarkIDX = 0;
	Display();
}

eOSState cOSDSurfer::ProcessKey(eKeys Key) {
	switch (Key) {
		case kUp|k_Repeat:
		case kUp:
		case kDown|k_Repeat:
		case kDown:
		case kLeft|k_Repeat:
		case kLeft:
		case kRight|k_Repeat:
		case kRight:
			DisplayMenu()->Scroll(NORMALKEY(Key) == kUp || NORMALKEY(Key) == kLeft,
						NORMALKEY(Key) == kLeft || NORMALKEY(Key) == kRight);
			//cStatus::MsgOsdTextItem(NULL, NORMALKEY(Key) == kUp);
			return osContinue;
		case k0: changeURL(0); return osContinue;
		case k1: changeURL(1); return osContinue;
		case k2: changeURL(2); return osContinue;
		case k3: changeURL(3); return osContinue;
		case k4: changeURL(4); return osContinue;
		case k5: changeURL(5); return osContinue;
		case k6: changeURL(6); return osContinue;
		case k7: changeURL(7); return osContinue;
		case k8: changeURL(8); return osContinue;
		case k9: changeURL(9); return osContinue;
		case kRed:
			 if(subBookmarkIDX - 1 >= -1)
				 subBookmarkIDX--; Display();
			 return osContinue;
		case kGreen:
			 if(subBookmarkIDX + 1 < numSubBookmarkIDX)
				 subBookmarkIDX++; Display();
			 return osContinue;
		default: break;
	}

	eOSState state = cOsdMenu::ProcessKey(Key);

	if (state == osUnknown) {
		switch (Key) {
			//case kGreen:
			//case kYellow: return osContinue;
			case kOk:     return osBack;
			case kBack:   return osBack;
			default: break;
		}
	}
	return state;
}

// --- cMenuSetupSurfer -------------------------------------------------------
class cMenuSetupSurfer : public cMenuSetupPage {
private:
protected:
	virtual void Store(void);
public:
	cMenuSetupSurfer(void);
};

cMenuSetupSurfer::cMenuSetupSurfer(void) : cMenuSetupPage() {
	Add(new cMenuEditIntItem(tr("Lynx-Width"),   &lynx_width, 20, 80));
}

void cMenuSetupSurfer::Store(void) {
	SetupStore("Lynx-Width", lynx_width);
}

// --- cPluginSurfer ------------------------------------------------------------

class cPluginSurfer : public cPlugin {
private:
  // Add any member variables or functions you may need here.
public:
  cPluginSurfer(void);
  virtual ~cPluginSurfer();
  virtual const char *Version(void) { return VERSION; }
  virtual const char *Description(void) { return DESCRIPTION; }
  virtual const char *CommandLineHelp(void);
  virtual bool ProcessArgs(int argc, char *argv[]);
  virtual bool Initialize(void);
  virtual bool Start(void);
  virtual void Stop(void);
  virtual void Housekeeping(void);
  virtual const char *MainMenuEntry(void) { return MAINMENUENTRY; }
  virtual cOsdObject *MainMenuAction(void);
  virtual cMenuSetupPage *SetupMenu(void);
  virtual bool SetupParse(const char *Name, const char *Value);
  };

cPluginSurfer::cPluginSurfer(void) {
  // Initialize any member variables here.
  // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
  // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
}

cPluginSurfer::~cPluginSurfer() {
  // Clean up after yourself!
}

const char *cPluginSurfer::CommandLineHelp(void) {
  // Return a string that describes all known command line options.
  return NULL;
}

bool cPluginSurfer::ProcessArgs(int argc, char *argv[]) {
  // Implement command line argument processing here if applicable.
  return true;
}

bool cPluginSurfer::Initialize(void) {
  // Initialize any background activities the plugin shall perform.
  return true;
}

bool cPluginSurfer::Start(void) {
  // Start any background activities the plugin shall perform.
  return true;
}

void cPluginSurfer::Stop(void) {
  // Stop any background activities the plugin shall perform.
}

void cPluginSurfer::Housekeeping(void) {
  // Perform any cleanup or other regular tasks.
}

cOsdObject *cPluginSurfer::MainMenuAction(void) {
  // Perform the action when selected from the main VDR menu.
  return new cOSDSurfer;
}

cMenuSetupPage *cPluginSurfer::SetupMenu(void) {
  // Return a setup menu in case the plugin supports one.
  return new cMenuSetupSurfer;
}

bool cPluginSurfer::SetupParse(const char *Name, const char *Value) {
  // Parse your own setup parameters and store their values.
	if (!strcasecmp(Name, "Lynx-Width"))   {lynx_width = atoi(Value); return true; }
	else
		return false;
}

VDRPLUGINCREATOR(cPluginSurfer); // Don't touch this!
