/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <unistd.h>
#include <stdlib.h>
#include <limits.h>
#include <time.h>
#include <linux/input.h>
#include <cutils/klog.h>
#include "minui/minui.h"

#define NEXT_TIMEOUT_MS 5000
#define LAST_TIMEOUT_S  30

#define LOGE(x...) do { KLOG_ERROR("slideshow", x); } while (0)

static int input_cb(int fd, unsigned int epevents, void *data)
{
    struct input_event ev;
    int *key_code = (int *)data;

    *key_code = -1;

    if (ev_get_input(fd, epevents, &ev)) {
        return -1;
    }

    if (ev.type == EV_KEY) {
        *key_code = ev.code;
    }

    return 0;
}

static void clear()
{
    gr_color(0, 0, 0, 0);
    gr_clear();
    gr_flip();
}

static void draw(const char *resname)
{
    GRSurface* surface;
    int w, h, x, y;

    if (res_create_display_surface(resname, &surface) < 0) {
        LOGE("failed to create surface for %s\n", resname);
        return;
    }

    w = gr_get_width(surface);
    h = gr_get_height(surface);
    x = (gr_fb_width() - w) / 2;
    y = (gr_fb_height() - h) / 2;

    gr_blit(surface, 0, 0, w, h, x, y);
    gr_flip();

    res_free_surface(surface);
}

int usage()
{
    LOGE("usage: slideshow [-t timeout] image.png [image2.png ...] last.png\n");
    return EXIT_FAILURE;
}

int main(int argc, char **argv)
{
    int key_code = -1;
    int input = false;
    int opt;
    long int timeout = NEXT_TIMEOUT_MS;
    time_t start;

    while ((opt = getopt(argc, argv, "t")) != -1) {
        switch (opt) {
        case 't':
            timeout = strtol(optarg, NULL, 0);

            if (timeout < 0 || timeout >= LONG_MAX) {
                timeout = NEXT_TIMEOUT_MS;
                LOGE("invalid timeout %s, defaulting to %ld\n", optarg,
                    timeout);
            }
            break;
        default:
            return usage();
        }
    }

    if (optind >= argc) {
        return usage();
    }

    if (gr_init() == -1 || ev_init(input_cb, &key_code) == -1) {
        LOGE("failed to initialize minui\n");
        return EXIT_FAILURE;
    }

    /* display all images except the last one, switch to next image after
     * timeout or user input */

    while (optind < argc - 1) {
        draw(argv[optind++]);

        if (ev_wait(timeout) == 0) {
            ev_dispatch();

            if (key_code != -1) {
                input = true;
            }
        }
    };

    /* if there was user input while showing the images, display the last
     * image and wait until the power button is pressed or LAST_TIMEOUT_S
     * has elapsed */

    if (input) {
        start = time(NULL);
        draw(argv[optind]);

        do {
            if (ev_wait(timeout) == 0) {
                ev_dispatch();
            }

            if (time(NULL) - start >= LAST_TIMEOUT_S) {
                break;
            }
        } while (key_code != KEY_POWER);
    }

    clear();
    gr_exit();
    ev_exit();

    return EXIT_SUCCESS;
}
