/*
 * Small tool to call xpdf with the given file and zap one page forward/back
 * as soon as the user presses A or B on his wiimote
 *
 *
 * Copyright (c) 2008-2009 Michael Stapelberg and contributors
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or other
 *   materials provided with the distribution.
 * 
 * * Neither the name of Michael Stapelberg, DustFS nor the names of its contributors
 *   may be used to endorse or promote products derived from this software without
 *   specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 */
#include <cwiid.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

cwiid_wiimote_t *wiimote;
int slide_number = 1;
const char *pdf_file;

/*
 * Launch xpdf with the given page number
 *
 */
static void launch_xpdf() {
	char *buffer;
	if (asprintf(&buffer, "xpdf -fullscreen -remote wiipdf-\"%s\" \"%s\" %d", pdf_file, pdf_file, slide_number) == -1) {
		fprintf(stderr, "Error allocating memory\n");
		exit(1);
	}

	if (system(buffer) != 0) {
		fprintf(stderr, "Error executing xpdf\n");
		exit(1);
	}
}

static void quit_xpdf() {
	char *buffer;
	if (asprintf(&buffer, "xpdf -quit -remote wiipdf-\"%s\"", pdf_file) == -1) {
		fprintf(stderr, "Error allocating memory\n");
		exit(1);
	}
	if (system(buffer) != 0) {
		fprintf(stderr, "Error executing xpdf\n");
		exit(1);
	}
}

/*
 * Give a short rumble as feedback for a successful operation
 *
 */
static void short_rumble() {
	cwiid_set_rumble(wiimote, 1);
	usleep(125000);
	cwiid_set_rumble(wiimote, 0);
}

static void next_slide() {
	short_rumble();
	slide_number++;
	launch_xpdf();
}

static void prev_slide() {
	short_rumble();
	slide_number--;
	launch_xpdf();
}

/*
 * Callback-function for all kind of events (which we enabled before)
 *
 */
static void msg_callback(cwiid_wiimote_t *msg_wiimote, int type, union cwiid_mesg *mesg,
			 struct timespec *time) {
	if (type == CWIID_MESG_BTN) {
		struct cwiid_btn_mesg *btn_msg = (struct cwiid_btn_mesg*)mesg;
		if (btn_msg->buttons == CWIID_BTN_A)
			next_slide();
		else if (btn_msg->buttons == CWIID_BTN_B)
			prev_slide();
		else if (btn_msg->buttons == CWIID_BTN_HOME) {
			quit_xpdf();
			exit(0);
		}
	}
}

int main(int argc, char *argv[]) {
	bdaddr_t wiimote_addr;

	if (argc != 3) {
		fprintf(stderr, "Syntax: %s <wiimote-bluetooth-id> <pdf>\n", argv[0]);
		fprintf(stderr, "Put your wiimote in discoverable mode after starting wiipdf\n");
		fprintf(stderr, "(Press button 1 and 2 at the same time)\n");
		return 1;
	}

	if (str2ba(argv[1], &wiimote_addr)) {
		fprintf(stderr, "Invalid bluetooth ID (use hcitool scan)\n");
		return 1;
	}

	pdf_file = argv[2];

	printf("Waiting for wiimote %s...\n", argv[1]);
	if ((wiimote = cwiid_open(&wiimote_addr, 0)) == NULL) {
		fprintf(stderr, "Could not connect to wiimote\n");
		return 1;
	}
	printf("Connection to wiimote established\n");
	/* Set LEDs 2 and 3 to on to signalize a successful link */
	cwiid_set_led(wiimote, CWIID_LED2_ON | CWIID_LED3_ON);

	if (cwiid_command(wiimote, CWIID_CMD_RPT_MODE, CWIID_RPT_STATUS | CWIID_RPT_BTN)) {
		fprintf(stderr, "Could not enable reporting mode\n");
		return 2;
	}

	if (cwiid_enable(wiimote, CWIID_FLAG_MESG_IFC)) {
		fprintf(stderr, "Could not enable message mode\n");
		return 3;
	}

	if (cwiid_set_mesg_callback(wiimote, msg_callback)) {
		fprintf(stderr, "Could not set callback\n");
		return 4;
	}

	/* Fortunately, xpdf blocks, so we just run as long as xpdf runs */
	launch_xpdf();

	return 0;
}
