#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>            /* shape.h の前に必要 */
#include <X11/extensions/shape.h> /* Shape Extension    */
#include <Imlib.h>
#include <stdio.h>


static Display* display;
static Window window;
static ImlibData*  imlib_data;
static ImlibImage* imlib_image;
static Pixmap pixmap;
static Pixmap mask;
static int width;
static int height;


static void render( void );
static void update_image( void );
static void flip_horizontal( void );
static void flip_vertical( void );


int
main( int argc, char** argv )
{
	int screen;

	if ( argc <= 1 ) {
		fprintf( stderr, "画像ファイルを指定してください。\n" );
		exit(1);
	}

	display = XOpenDisplay( NULL );
	screen  = DefaultScreen( display );

	if ( ( imlib_data = Imlib_init( display ) ) == NULL ) {
		fprintf( stderr, "Imlib の初期化に失敗しました。\n" );
		XCloseDisplay( display );
		exit(1);
	}

	if ( ( imlib_image = Imlib_load_image( imlib_data, argv[1] ) ) == NULL ) {
		fprintf( stderr, "画像の読み込みに失敗しました。\n" );
		XCloseDisplay( display );
		exit(1);
	}

	width  = imlib_image->rgb_width;
	height = imlib_image->rgb_height;

	window = XCreateSimpleWindow( 
		display, 
		DefaultRootWindow( display ),
		width,
		height,
		width,
		height,
		0,
		BlackPixel( display, screen ),
		BlackPixel( display, screen ) 
		);

	XSelectInput( display, window, StructureNotifyMask | KeyPressMask );
	XMapWindow( display, window );
	render();
	update_image();

	while ( 1 ) {
		int esc_pressed = 0;
		XEvent event;
		KeySym key_sym;

		XNextEvent( display, &event );

		switch ( event.type ) {
			case KeyPress:
				XLookupString( &( event.xkey ), 
				        NULL, 0, &key_sym, NULL );

				switch ( key_sym ) {
					case XK_Left:
					case XK_Right:
						flip_horizontal();
						break;
					case XK_Up:
					case XK_Down:
						flip_vertical();
						break;
					case XK_Escape:
						esc_pressed = 1;
						break;
				}

				break;

			case ConfigureNotify:
				width  = event.xconfigure.width;
				height = event.xconfigure.height;
				Imlib_free_pixmap( imlib_data, pixmap );
				render();
				update_image();
				break;
		}

		if ( esc_pressed ) {
			break;
		}
	}


	Imlib_free_pixmap( imlib_data, pixmap );
	Imlib_kill_image( imlib_data, imlib_image );
	XDestroyWindow( display, window );
	XCloseDisplay( display );

	return 0;
}


static void
render( void )
{
	Imlib_render( imlib_data, imlib_image, width, height );
	pixmap = Imlib_move_image( imlib_data, imlib_image );
	mask = Imlib_move_mask( imlib_data, imlib_image );
}


static void
update_image( void )
{
	XSetWindowBackgroundPixmap( display, window, pixmap );
	
	if ( mask ) {
		XShapeCombineMask( display, window, 
			   ShapeBounding, 0, 0, mask, ShapeSet );
	}

	XClearWindow( display, window );
	XSync( display, False );
}


static void
flip_horizontal( void )
{
	Imlib_free_pixmap( imlib_data, pixmap );
	Imlib_flip_image_horizontal( imlib_data, imlib_image );
	render();
	update_image();
}


static void
flip_vertical( void )
{
	Imlib_free_pixmap( imlib_data, pixmap );
	Imlib_flip_image_vertical( imlib_data, imlib_image );
	render();
	update_image();
}


/* End of x_imlib.c */
