#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_ttf.h"
#include "SDL_mixer.h"
#include "SDL_thread.h"
#include "key.h"
#include "sdl_shape.h"
#include "res_text.h"

/********FM********/
#define AUTO_SEEK 0x0
#define AUTO_SEEK_JAPAN 0x01
#define SET_FREQ 0x02
#define SET_VOLUME 0x03
#define READ_VOLUME 0x04
#define SET_STEREO 0x05
#define FM_POWER_ON 0x06
#define FM_POWER_OFF 0x07
#define SET_MUTE  0x08
/*******************/

#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 272
#define SCREEN_BPP 16

#define PIX_PATH "./pixmap/"
#define PIX_1 PIX_PATH"1.jpg"
#define PIX_2 PIX_PATH"2.jpg"
#define PIX_3 PIX_PATH"3.jpg"
#define PIX_4 PIX_PATH"4.jpg"
#define PEOPLE PIX_PATH"people.jpg"
#define KEY_BG PIX_PATH"key_bg.png"
#define TVOUT PIX_PATH"tvout.png"
#define GSENSOR PIX_PATH"gsensor.png"
#define GSENSOR_FAIL PIX_PATH"gsensor_fail.png"
#define GSENSOR_FAIL_WRITE PIX_PATH"gsensor_fail_write.png"
#define FM PIX_PATH"fm.png"
#define FM_ST1 PIX_PATH"st1.png"
#define FM_ST2 PIX_PATH"st2.png"
#define FM_ST3 PIX_PATH"st3.png"
#define FM_INFO1 PIX_PATH"fm_info1.png"
#define FM_INFO2 PIX_PATH"fm_info2.png"

#define MUSIC_PATH "./music/"
#define TEST_MUSIC MUSIC_PATH"test.wav"
#define RECORD_MUSIC MUSIC_PATH"record.wav"
#define MUSIC_FAIL PIX_PATH"music_fail.png"
#define SOUND PIX_PATH"sound.png"

#define RECORD PIX_PATH"record.png"
#define RECORDING PIX_PATH"recording.png"
#define PLAYING PIX_PATH"playing.png"
#define WAIT_1 PIX_PATH"1.png"
#define WAIT_2 PIX_PATH"2.png"
#define WAIT_3 PIX_PATH"3.png"

static int key_count = 0;
static char key_flag[12]; 

static SDL_Color Bcolor = { 0, 0, 0 };
static SDL_Color Wcolor = { 255, 255, 255};
//static SDL_Color Bcolor = { 0, 0, 0 };

static SDL_Rect people_rect_up = {190,16,100,100};
static SDL_Rect people_rect_down = {190,156,100,100};
static SDL_Rect people_rect_left = {40,86,100,100};
static SDL_Rect people_rect_right = {340,86,100,100};

static SDL_Rect bg_rect = {0,0,480,272};
static SDL_Rect info_rect = {145,36,150,60};
static SDL_Rect info_rect2 = {165,36,150,30};
static SDL_Rect info_rect3 = {160,36,150,60};

static SDL_Rect key_rect[12] = 
{
  {80,89,20,20},
  {80,127,20,20},
  {61,108,20,20},
  {99,108,20,20},
  {392,108,20,20},
  {373,127,20,20},
  {373,89,20,20},
  {354,108,20,20},
  {80,30,20,20},
  {373,30,20,20},
  {80,208,20,20},
  {373,208,20,20},
};

static int goon = 1;
static int tv_out = 0;
SDL_Surface *screen = NULL;
SDL_Surface *key_bg = NULL;	
SDL_Surface *people = NULL;
SDL_Surface *tvout = NULL;
SDL_Surface *sound = NULL;
SDL_Surface *music_fail = NULL;
SDL_Surface *gsensor = NULL;
SDL_Surface *gsensor_fail = NULL;
SDL_Surface *gsensor_fail_write = NULL;
SDL_Surface *fm = NULL;
SDL_Surface *fm_info1 = NULL;
SDL_Surface *fm_info2 = NULL;
SDL_Surface *fm_st1 = NULL;
SDL_Surface *fm_st2 = NULL;
SDL_Surface *fm_st3 = NULL;
Mix_Music *music = NULL;

SDL_Surface *record = NULL;
SDL_Surface *recording = NULL;
SDL_Surface *playing = NULL;
SDL_Surface *wait_1 = NULL;
SDL_Surface *wait_2 = NULL;
SDL_Surface *wait_3 = NULL;

static void check_quit_sound_test();
int start_record(char *filename);

SDL_Surface *load_image(const char *filename)
{
  //The image that's loaded
  SDL_Surface* loadedImage = NULL;

  //The optimized surface that will be used
  SDL_Surface* optimizedImage = NULL;

  //Load the image
  loadedImage = IMG_Load( filename );

  //If the image loaded
  if( loadedImage != NULL )
  {
    //Create an optimized surface
    optimizedImage = SDL_DisplayFormat( loadedImage );

    //Free the old surface
    SDL_FreeSurface( loadedImage );
  }

  //Return the optimized surface
  return optimizedImage;
}

static void init_flag()
{
  int i;
  for(i=0;i<12;i++)
    key_flag[i] = 0;
}
static void init_key_test()
{
  int i;

  SDL_BlitSurface(key_bg, NULL,screen, &bg_rect);
  sdl_set_pen(&Bcolor, 1, screen);
  for(i=0;i<12;i++)
    //		sdl_draw_rect_dashed(screen, &key_rect[i], 2);
    sdl_draw_rect(screen, &key_rect[i]);

  //	SDL_BlitSurface(people, NULL,screen, &people_rect);

  SDL_Flip(screen);
}
static void process_key_down(int value)
{
  if(key_flag[value] == 0)
  {
    key_flag[value] = 1;
    key_count++;
    sdl_set_pen(&Bcolor, 1, screen);
    sdl_draw_rect_solid(screen, &key_rect[value]);
  }
  else if(key_flag[value] == 1)
  {
    key_flag[value] = 0;
    key_count--;
    sdl_set_pen(&Wcolor, 1, screen);
    sdl_draw_rect_solid(screen, &key_rect[value]);
    sdl_set_pen(&Bcolor, 1, screen);
    //		sdl_draw_rect_dashed(screen, &key_rect[value], 2);
    sdl_draw_rect(screen, &key_rect[value]);
  }
  else printf("error\n");;

  SDL_Flip(screen);

  if(key_count == 12)
    goon = 0;
}


static void process_key(int keyval)
{
  switch(keyval)
  {
    case KEY_UP:
      process_key_down(0);
      break;
    case KEY_DOWN:
      process_key_down(1);
      break;
    case KEY_LEFT:
      process_key_down(2);
      break;
    case KEY_RIGHT:
      process_key_down(3);
      break;
    case KEY_A:
      process_key_down(4);
      break;
    case KEY_B:
      process_key_down(5);
      break;
    case KEY_Y:
      process_key_down(6);
      break;
    case KEY_X:
      process_key_down(7);
      break;
    case KEY_L:
      process_key_down(8);
      break;
    case KEY_R:
      process_key_down(9);
      break;
    case KEY_SEL:
      process_key_down(10);
      break;
    case KEY_START:
      process_key_down(11);
      break;
    default: break;
  }	
}
static void process_key_sensor(int keyval)
{
  static int count = 0;
  SDL_BlitSurface(gsensor, NULL,screen, &bg_rect);
  switch(keyval)
  {
    case KEY_UP:
      SDL_BlitSurface(people, NULL,screen, &people_rect_up);
      break;
    case KEY_DOWN:
      SDL_BlitSurface(people, NULL,screen, &people_rect_down);
      break;
    case KEY_LEFT:
      SDL_BlitSurface(people, NULL,screen, &people_rect_left);
      break;
    case KEY_RIGHT:
      SDL_BlitSurface(people, NULL,screen, &people_rect_right);
      break;

    default: 
      goon = 0;				
      break;
  }
  SDL_Flip(screen);
  count++;
  if(count > 5)
    goon = 0;	
}

static void process_key_tvout(int keyval)
{
  switch(keyval)
  {
    case KEY_A:
      if(tv_out == 0)
      {
        tv_out = 1;
        system("echo 1 > /proc/jz/tvout");
      }
      else
      {
        tv_out = 0;
        system("echo 0 > /proc/jz/tvout");
      }
      break;
    case KEY_B:
      goon = 0;
      break;
    default: 
      break;
  }
}
static void process_key_sound(int keyval)
{
  switch(keyval)
  {
    case KEY_B:
      check_quit_sound_test();
      goon = 0;
      break;
    default: 
      break;
  }
}
static void window_loop(int value)
{
  //The event structure
  SDL_Event event;

  while(goon)
  {
    //While there's events to handle
    if( SDL_PollEvent( &event ) )
    {
      //If a key was pressed
      if( event.type == SDL_KEYDOWN )
      {
        //		printf("xxx\n");
        if(1 == value)
          process_key(event.key.keysym.sym);
        else if(0 == value)
          process_key_sensor(event.key.keysym.sym);
        else if(2 == value)
          process_key_tvout(event.key.keysym.sym);
        else if(3 == value)
          process_key_sound(event.key.keysym.sym);
      }

      //If the user has Xed out the window
      else if( event.type == SDL_QUIT )
      {
        //Quit the program
        goon = 0;
      }

    }

  }
}	

static void key_test()
{
  key_bg = load_image(KEY_BG);
  init_flag();
  init_key_test();
  goon = 1;
  window_loop(1);
  SDL_FreeSurface(key_bg);
}
static void lcd_test()
{
  SDL_Surface *pix1 = NULL;
  SDL_Surface *pix2 = NULL;
  SDL_Surface *pix3 = NULL;
  SDL_Surface *pix4 = NULL;

  pix1 = load_image(PIX_1);
  pix2 = load_image(PIX_2);
  pix3 = load_image(PIX_3);
  pix4 = load_image(PIX_4);

  int i = 1;
  while(i--)
  {
    SDL_BlitSurface(pix1,NULL,screen,NULL);
    SDL_Flip(screen);
    usleep(500*1000);
    SDL_BlitSurface(pix2,NULL,screen,NULL);
    SDL_Flip(screen);
    usleep(500*1000);
    SDL_BlitSurface(pix3,NULL,screen,NULL);
    SDL_Flip(screen);
    usleep(500*1000);
    SDL_BlitSurface(pix4,NULL,screen,NULL);
    SDL_Flip(screen);
    usleep(500*1000);
  }

  SDL_FreeSurface(pix1);
  SDL_FreeSurface(pix2);
  SDL_FreeSurface(pix3);
  SDL_FreeSurface(pix4);
}

static int  load_music(const char* music_file)
{
  //Load the music
  music = Mix_LoadMUS(music_file);
  //If there was a problem loading the music
  if( music == NULL )
  {

    music_fail = load_image(MUSIC_FAIL);
    SDL_BlitSurface(music_fail, NULL,screen, &info_rect2);
    SDL_Flip(screen);

    printf("Load Sound file error\n");
    return -1;
  }

  playing = load_image(PLAYING);
  SDL_BlitSurface(playing, NULL,screen, &info_rect3);
  SDL_Flip(screen);

  //If there is no music playing
  if( Mix_PlayingMusic() == 0 )
  {
    //Play the music
    if( Mix_PlayMusic( music, -1 ) == -1 )
    {
      return -1;
    }
  }
  return 0;

}
static void check_quit_sound_test()
{
  if( Mix_PlayingMusic() != 0 )
  {
    //Stop the music
    Mix_HaltMusic();
    Mix_FreeMusic( music );
  }
}
static void sound_test()
{
  sound = load_image(SOUND);
  SDL_BlitSurface(sound, NULL,screen, &bg_rect);
  SDL_Flip(screen);
  if(0 == load_music(TEST_MUSIC))
    SDL_Delay(10000);
  else SDL_Delay(3000);
  /*
     goon = 1;
     window_loop(3);
     */
  check_quit_sound_test();
  SDL_FreeSurface(sound);
}
static void record_test()
{
  record = load_image(RECORD);
  SDL_BlitSurface(record, NULL,screen, &bg_rect);
  SDL_Flip(screen);
  wait_1 = load_image(WAIT_1);
  wait_2 = load_image(WAIT_2);
  wait_3 = load_image(WAIT_3);
  recording = load_image(RECORDING);
  SDL_BlitSurface(wait_3, NULL,screen, &info_rect3);
  SDL_Flip(screen);
  SDL_Delay(1000);
  SDL_BlitSurface(wait_2, NULL,screen, &info_rect3);
  SDL_Flip(screen);
  SDL_Delay(1000);
  SDL_BlitSurface(wait_1, NULL,screen, &info_rect3);
  SDL_Flip(screen);
  SDL_Delay(1000);
  SDL_BlitSurface(recording, NULL,screen, &info_rect3);
  SDL_Flip(screen);
  start_record(RECORD_MUSIC);
  if(0 == load_music(RECORD_MUSIC))
    SDL_Delay(10000);
  else SDL_Delay(3000);
  check_quit_sound_test();

  SDL_FreeSurface(record);
  SDL_FreeSurface(recording);
  SDL_FreeSurface(wait_1);
  SDL_FreeSurface(wait_2);
  SDL_FreeSurface(wait_3);
  remove(RECORD_MUSIC);
}
static void Gsensor()
{
  people = load_image(PEOPLE);
  gsensor = load_image(GSENSOR);
  gsensor_fail = load_image(GSENSOR_FAIL);
  gsensor_fail_write = load_image(GSENSOR_FAIL_WRITE);
  SDL_BlitSurface(gsensor, NULL,screen, &bg_rect);
  SDL_Flip(screen);
  //        system("echo 1 > /proc/jz/gsensor");
  FILE *fp_g = fopen("/proc/jz/gsensor","wb");
  if(fp_g == NULL)
  {
    printf("Open Gsensor Fail\n");
    SDL_BlitSurface(gsensor_fail, NULL,screen, &bg_rect);
    SDL_Flip(screen);
    return;
  }
  else
  {
    char xbuff[128] = {};
    memset(xbuff,'\0',128);
    snprintf(xbuff,128,"%d",1);
    int count = fwrite(xbuff,sizeof(char),128,fp_g);
    if(128 != count)
    {
      printf("Write Gsensor Fail\n");
      SDL_BlitSurface(gsensor_fail_write, NULL,screen, &bg_rect);
      SDL_Flip(screen);
    }
    printf("count = %d\n",count);
    fflush(fp_g);
    fsync(fileno(fp_g));
    fclose(fp_g);
  }
  goon = 1;
  window_loop(0);
  SDL_FreeSurface(gsensor);
  SDL_FreeSurface(people);
  SDL_FreeSurface(gsensor_fail);
  SDL_FreeSurface(gsensor_fail_write);
  system("echo 0 > /proc/jz/gsensor");
}
static void tvout_test()
{
  tvout = load_image(TVOUT);
  SDL_BlitSurface(tvout, NULL,screen, &bg_rect);
  SDL_Flip(screen);
  /*	
        goon = 1;
        window_loop(2);
        */
  SDL_Delay(1000);	
  system("echo 1 > /proc/jz/tvout");
  SDL_Delay(3000);	
  system("echo 0 > /proc/jz/tvout");

  SDL_FreeSurface(tvout);
}
static void fm_test()
{
  fm = load_image(FM);
  fm_info1 = load_image(FM_INFO1);
  fm_info2 = load_image(FM_INFO2);
  fm_st1 = load_image(FM_ST1);
  fm_st2 = load_image(FM_ST2);
  fm_st3 = load_image(FM_ST3);
  SDL_BlitSurface(fm, NULL,screen, &bg_rect);
  SDL_Flip(screen);

  int flag = 0;
  int freq = 870;
  int fd = open("/dev/fm_rda5807p",O_RDWR,0);
  if (fd < 0){
    printf("can not open /dev/fm_rda5807p device!\n");
    return;
  }
  else printf("open ok\n");
  ioctl(fd,FM_POWER_ON,NULL);


  for(freq = 870;freq < 1080;freq++)
  {
    switch(freq%3)
    {
      case 0:
        SDL_BlitSurface(fm_st1, NULL,screen, &info_rect);
        break;
      case 1:
        SDL_BlitSurface(fm_st2, NULL,screen, &info_rect);
        break;
      case 2:
        SDL_BlitSurface(fm_st3, NULL,screen, &info_rect);
        break;
    }		
    SDL_Flip(screen);
    if(ioctl(fd,AUTO_SEEK,&freq))
    {
      flag = 1;
      break;
    }		
  }
  if(flag == 1)
  {
    SDL_BlitSurface(fm_info1, NULL,screen, &info_rect);
    SDL_Flip(screen);
    ioctl(fd,SET_FREQ,&freq);
    SDL_Delay(6000);
  }		
  else
  {
    SDL_BlitSurface(fm_info2, NULL,screen, &info_rect);
    SDL_Flip(screen);
    SDL_Delay(2000);
  }

  /**************************************************/
#if 0
  goon = 1;
  //The event structure
  SDL_Event event;

  while(goon)
  {
    //While there's events to handle
    if( SDL_PollEvent( &event ) )
    {
      //If a key was pressed
      if( event.type == SDL_KEYDOWN )
      {
        goon = 0;
      }
    }
  }
#endif
  /**************************************************/
  //	fm_poweroff();
  ioctl(fd,FM_POWER_OFF,NULL);

  close(fd);

  SDL_FreeSurface(fm);
  SDL_FreeSurface(fm_info1);
  SDL_FreeSurface(fm_info2);

  return;

}
static int init_sdl()
{
  if( SDL_Init( SDL_INIT_VIDEO ) == -1 )
  {
    printf("SDL_Init(SDL_INIT_VIDEO) FAIL!\n");
    return -1;
  }

  SDL_ShowCursor(0);

  screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

  //If there was an error in setting up the screen
  if( screen == NULL )
  {
    printf("SDL_SetVideoMode FAIL!\n");
    return -1;
  }

  //Initialize SDL_ttf
  if( TTF_Init() == -1 )
  {
    printf("TTF_Init FAIL!\n");
    //        return -1;
  }

  //Initialize SDL_mixer
  if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 )
    //	 if( Mix_OpenAudio(0, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 )
  {
    printf("Mix_OpenAudio FAIL\n");
    //        return -1;
  }

  //If everything initialized fine
  return 0;
}
static void quit_sdl()
{

  //Quit SDL_mixer
  Mix_CloseAudio();

  //Quit SDL_ttf
  TTF_Quit();

  //Quit SDL
  SDL_Quit();
}

TTF_Font * myFont;
SDL_Surface * face1,* face2,* face3;


void Apply_surface_new(int x,int y,SDL_Surface* source,SDL_Surface* destination,SDL_Rect* clip)
{
	SDL_Rect offset;
	offset.x = x;
	offset.y = y;
	SDL_BlitSurface(source,clip,destination,&offset);
}


int main(int argc ,char** argv)
{
  printf("Start Test\n");
  if(-1 == init_sdl())
  {
    printf("Init Error\n");
    quit_sdl();	
    return 0;	
  }
  system("echo 1 > /proc/jz/lcd_flush");
  lcd_test();
  key_test();
  Gsensor();
  sound_test();
  record_test();
  tvout_test();
  fm_test();
  system("echo 0 > /proc/jz/lcd_flush");
  printf("End L009 Test\n");
  quit_sdl();
  return 0;
}
