// egl_bar.c - self-contained example of a vertical bar moving across the screen.
// compile with  gcc -Wall -O0 -g -o egl_bar egl_bar.c log.c -lX11 -lEGL -lGLESv2 -lm
#include <stdio.h>
#include <math.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>

#include <GLES2/gl2.h>
#include <EGL/egl.h>

#include <alsa/asoundlib.h>

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>

#include "aiplay.h"
#include "raspberrypi_spi/LocalDimming/interface.h"

#if 1
#define INPUT_VIDEO_FILE "/mnt/data/media/tu-shou-pan-yan.mp4"
#define INPUT_VIDEO_FILE_1 "/usr/local/bin/Videos/待机.mp4"
#define INPUT_VIDEO_FILE_2 "/usr/local/bin/Videos/回应.mp4"
#define INPUT_VIDEO_FILE_3 "/usr/local/bin/Videos/右转.mp4"
#define INPUT_VIDEO_FILE_4 "/usr/local/bin/Videos/左转.mp4"
#else
#define INPUT_VIDEO_FILE "/home/developer/Pictures/tu-shou-pan-yan.mp4"
#define INPUT_VIDEO_FILE_1 "/home/developer/Videos/待机.mp4"
#define INPUT_VIDEO_FILE_2 "/home/developer/Videos/回应.mp4"
#define INPUT_VIDEO_FILE_3 "/home/developer/Videos/左转.mp4"
#define INPUT_VIDEO_FILE_4 "/home/developer/Videos/右转.mp4"
#endif

#define log_trace printf
#define log_debug printf
#define log_info printf
#define log_warn printf
#define log_error printf
#define log_fatal printf

typedef struct
{
  aiplay_t *ap;
} play_callback_ctx;


static const char *g_current_file_name = INPUT_VIDEO_FILE_1;
static int g_current_file_id = 0;

static void aiplay_event_cb(void *user_ctx, aiplay_event_t event)
{
  // log_debug("play_callback type %d\n", event.type);

  play_callback_ctx *ctx = (play_callback_ctx *)user_ctx;
  if (event.type == 1)
  {
    g_current_file_name = INPUT_VIDEO_FILE_1;
    aiplay_play(ctx->ap, INPUT_VIDEO_FILE_1);
  }
  else if (event.type == 2)
  {
    if (event.content == 0){
       printf("id = %d\n", g_current_file_id);
      if (strcmp(g_current_file_name, INPUT_VIDEO_FILE_1) == 0){
        g_current_file_id = 1;
        printf("\r\rg_id = %d\n", g_current_file_id);
      }else if (strcmp(g_current_file_name, INPUT_VIDEO_FILE_2) == 0){
        g_current_file_id = 2;   
        printf("\r\rg_id = %d\n", g_current_file_id);
      }else if (strcmp(g_current_file_name, INPUT_VIDEO_FILE_3) == 0){
        g_current_file_id = 3;
        printf("\r\rg_id = %d\n", g_current_file_id);
      }else if (strcmp(g_current_file_name, INPUT_VIDEO_FILE_4) == 0){
        g_current_file_id = 4;
        printf("\r\rg_id = %d\n", g_current_file_id);
      }
    }
    eachPicWrite(g_current_file_id, event.content);
    //log_debug("play_callback id %d\n", event.content);
    
  }

  // log_debug("play_callback exit\n");
}

static void audio_event_cb(void *user_ctx, int id)
{
  play_callback_ctx *ctx = (play_callback_ctx *)user_ctx; printf("audio_event_g_id = %d\n", id);
  if (id == 1){
    g_current_file_name = INPUT_VIDEO_FILE_1;
    aiplay_play(ctx->ap, INPUT_VIDEO_FILE_1);
  }else if (id == 2){
    g_current_file_name = INPUT_VIDEO_FILE_2;
    aiplay_play(ctx->ap, INPUT_VIDEO_FILE_2); 
  }else if (id == 3){
    g_current_file_name = INPUT_VIDEO_FILE_3;
    aiplay_play(ctx->ap, INPUT_VIDEO_FILE_3);
  }if (id == 4){
    g_current_file_name = INPUT_VIDEO_FILE_4;
    aiplay_play(ctx->ap, INPUT_VIDEO_FILE_4);
  }
}

int get_audio_device_id()
{
    snd_pcm_t *handle;
    snd_pcm_info_t *info;
    snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK; // 选择播放流

    int card = -1, usb_card = -1;
    int err;

    while (usb_card == -1) {
        err = snd_card_next(&card);
        if (err < 0) {
            fprintf(stderr, "没有可用的声卡设备.\n");
            break;
        }

        if (card < 0) {
            fprintf(stderr, "没有找到声卡.\n");
            break;
        }


        char cardName[32];
        sprintf(cardName, "hw:%d", card);

        if ((err = snd_pcm_open(&handle, cardName, stream, 0)) < 0) {
            fprintf(stderr, "无法打开声卡 %s: %s\n", cardName, snd_strerror(err));
            continue;
        }

        snd_pcm_info_malloc(&info);
        snd_pcm_info(handle, info);

        printf("声卡 %d: %s\n", card, snd_pcm_info_get_name(info));
	if (strncmp("USB Audio", snd_pcm_info_get_name(info), strlen("USB Audio")) == 0){
		usb_card = card;
	}

        snd_pcm_info_free(info);
        snd_pcm_close(handle);

    }

    return usb_card;
}

int main(int argc, char **argv)
{
  //system("ffplay -volume 255 -nodisp -autoexit /usr/local/bin/Videos/aaaa.mp3 &");
  //system("aplay /usr/local/bin/Videos/tech.wav &");
  //system("test_alsa /usr/local/bin/Videos/aaaa.mp3 &");
  //system("cvlc --play-and-exit --aout alsa --alsa-audio-device hw:3,0 /usr/local/bin/Videos/aaaa.mp3 &");
	printf("USB Auido device id: %d\n", get_audio_device_id());
	char buf[256] = {0};
	snprintf(buf, 256, "cvlc --play-and-exit --aout alsa --alsa-audio-device hw:%d,0 /usr/local/bin/Videos/aaaa.mp3 &", get_audio_device_id());
	system(buf);  
  
  LocalDimming_Init();
  sleep(2);
  LocalDimming_Init();

  Display *x_display = XOpenDisplay(NULL);
  while (x_display == NULL)
  {
    log_fatal("cannot connect to X server");
    sleep(3);
    x_display = XOpenDisplay(NULL);
  }

  // 获取默认屏幕
  int screen_num = DefaultScreen(x_display);

  // 创建一个透明的光标来隐藏鼠标指针
  Pixmap cursor_pixmap = XCreatePixmap(x_display, DefaultRootWindow(x_display), 1, 1, 1);
  XColor dummy_color;
  Cursor invisible_cursor = XCreatePixmapCursor(x_display, cursor_pixmap, cursor_pixmap, &dummy_color, &dummy_color, 0, 0);

  // 隐藏鼠标指针
  XDefineCursor(x_display, RootWindow(x_display, screen_num), invisible_cursor);
  XFlush(x_display);

  Window root = DefaultRootWindow(x_display); // get the root window (usually the whole screen)
  int root_x, root_y;
  unsigned int root_w, root_h, root_border_width, root_depth;
  Window root_again;
  XGetGeometry(x_display, root, &root_again, &root_x, &root_y, &root_w, &root_h, &root_border_width, &root_depth);
  log_info("Matching X11 root window geometry: +%d,%d %dx%d border %d, %dbpp\n",
           root_x, root_y, root_w, root_h, root_border_width, root_depth);

  XSetWindowAttributes swa;
  swa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask | FocusChangeMask;

  Window win = XCreateWindow(x_display, root,
                             0, 0, root_w, root_h, 0,
                             CopyFromParent, InputOutput,
                             CopyFromParent, CWEventMask,
                             &swa);

  XSetWindowAttributes xattr;

  xattr.override_redirect = False;
  XChangeWindowAttributes(x_display, win, CWOverrideRedirect, &xattr);

  int one = 1;
  XChangeProperty(
      x_display, win,
      XInternAtom(x_display, "_HILDON_NON_COMPOSITED_WINDOW", False),
      XA_INTEGER, 32, PropModeReplace,
      (unsigned char *)&one, 1);

  XWMHints hints;
  hints.input = True;
  hints.flags = InputHint;
  XSetWMHints(x_display, win, &hints);

  XMapWindow(x_display, win); // makes the window visible on the screen
  XStoreName(x_display, win, argv[0]);

  //// get identifiers for the provided atom name strings
  Atom wm_state = XInternAtom(x_display, "_NET_WM_STATE", False);
  Atom fullscreen = XInternAtom(x_display, "_NET_WM_STATE_FULLSCREEN", False);

  XEvent xev;
  memset(&xev, 0, sizeof(xev));

  xev.type = ClientMessage;
  xev.xclient.window = win;
  xev.xclient.message_type = wm_state;
  xev.xclient.format = 32;
  xev.xclient.data.l[0] = 1;
  xev.xclient.data.l[1] = fullscreen;
  XSendEvent( // set up event mask (which events we want to receive)
      x_display,
      DefaultRootWindow(x_display),
      False,
      SubstructureNotifyMask,
      &xev);

  XWindowAttributes gwa;
  XGetWindowAttributes(x_display, win, &gwa);

  aiplay_t *ap = aiplay_open((void *)win, gwa.width, gwa.height);

  play_callback_ctx user_ctx;
  user_ctx.ap = ap;

  aiplay_set_callback(ap, aiplay_event_cb, (void *)&user_ctx);

  aiplay_play(ap, INPUT_VIDEO_FILE_1);

  audio_set_callback(audio_event_cb, (void *)&user_ctx);
  xfm_Init();
  circleReading();

#if 0
  while (1)
  {
    XEvent event;
    XNextEvent(x_display, &event);

    if (event.type == KeyPress)
    {
      KeySym keySym;
      char keyChar;

      // 将键值转换为字符
      if (XLookupString(&event.xkey, &keyChar, 1, &keySym, NULL) == 1)
      {
        printf("按下数字键: %c\n", keyChar);
        if (keyChar == '1')
        {
          g_current_file_name = INPUT_VIDEO_FILE_1;
          aiplay_play(ap, g_current_file_name);
        }
        else if (keyChar == '2')
        {
          g_current_file_name = INPUT_VIDEO_FILE_2;
          aiplay_play(ap, g_current_file_name);
        }
        else if (keyChar == '3')
        {
          g_current_file_name = INPUT_VIDEO_FILE_3;
          aiplay_play(ap, g_current_file_name);
        }
        else if (keyChar == '4')
        {
          g_current_file_name = INPUT_VIDEO_FILE_4;
          aiplay_play(ap, g_current_file_name);
        }
        else if (keyChar == 'q')
        {
          break;
        }
      }
    }
    else if (event.type == FocusIn)
    {
      printf("窗口获得焦点\n");
      // 在这里处理窗口获得焦点事件
    }
    else if (event.type == FocusOut)
    {
      printf("窗口失去焦点\n");
      // 在这里处理窗口失去焦点事件
      // break;
    }
  }
#endif

  aiplay_close(ap);

  // 恢复默认光标并清理资源
  XUndefineCursor(x_display, RootWindow(x_display, screen_num));
  XFreeCursor(x_display, invisible_cursor);
  XFreePixmap(x_display, cursor_pixmap);

  XCloseDisplay(x_display);

  return 0;
}
