#include "mainwin.h"
#include "app.h"
#include <util/application.h>
#include <gui/requesters.h>
#include <gui/desktop.h>
#include <gui/dropdownmenu.h>
#include <gui/layoutview.h>
#include <gui/stringview.h>
#include <storage/file.h>
#include <util/resources.h>
#include <iostream.h>
#include <stdio.h>

#include <gui/image.h>
#include <gui/imageview.h>
#include <storage/memfile.h>

uint8 cIconPNG[] = {
	#include "icon.h"
};

void MainWin::HandleMessage(Message *msg)
{
	switch(msg->GetCode()) {
		case ID_SETFILTER:
			{
				Image *pImg = new BitmapImage( *(( BitmapImage* )m_Img2) );
				pImg->ApplyFilter( m_Dropdown->GetSelection() );
				if(m_ImageView->GetImage()) delete m_ImageView->GetImage();
				m_ImageView->SetImage( pImg );
			}
			break;
		case ID_QUIT:
			break;
		default:
			Window::HandleMessage(msg);
	}
}

MainWin::MainWin(const Rect & r)
	:Window(r, "MainWin", "Image Test", 0, CURRENT_DESKTOP)
{
	Rect bounds = GetBounds();
	
	bounds.left+=15;
	bounds.top+=15;
	bounds.bottom-=15;
	bounds.right-=15;

	try {	
		// To create an Image, we have to get image data from something,
		// for instance a file:
		File cFile( "icon.png" );
		m_Img1 = new BitmapImage( &cFile );

		// Or, a resource:
		Resources cRes( get_image_id() );
		ResStream* pcStream = cRes.GetResourceStream( "icon.png" );
		m_Img2 = new BitmapImage( pcStream );

		// Or, from memory:
		MemFile	cMemFile( cIconPNG, sizeof( cIconPNG ) );
		m_Img3 = new BitmapImage( &cMemFile );

		// Finally, from other images:
		m_Img4 = new BitmapImage( *(( BitmapImage* )m_Img2) );
		m_Img5 = new BitmapImage( *(( BitmapImage* )m_Img2) );
		m_Img6 = new BitmapImage( *(( BitmapImage* )m_Img2) );

		// The Image class defines a couple of methods for manipulating
		// the image data. Since these are defined in the Image class,
		// we don't need to know what kind of Image it is.
		m_Img1->ApplyFilter( Image::F_GRAY );
		//m_Img3->ApplyFilter( Image::F_HIGHLIGHT );
		m_Img3->ApplyFilter( ColorizeFilter( Color32_s(75,75,75) ) );
		m_Img3->ApplyFilter( GlowFilter( Color32_s(200,255,255), Color32_s(50,100,250,128), 5 ) );
		m_Img5->SetSize( Point( 128, 128 ) );
		m_Img6->SetSize( Point( 32, 32 ) );
		

		m_Img4->ApplyFilter( Image::F_ALPHA_TO_OVERLAY );

		// Other methods may be added to subclasses, but to use them we
		// would have to cast the Image object to that subclass. The class
		// name can be retrieved with ImageType(), so we can make sure we
		// don't do anything stupid:
		if( m_Img4->ImageType() == "BitmapImage" ) {
			cout << "m_Img4 is a BitmapImage" << endl;			
		}

		// Dropdown menu for filters:
		m_Dropdown = new DropdownMenu( Rect(), "m_Dropdown" );
		m_Dropdown->SetReadOnly();
		m_Dropdown->AppendItem( "F_NONE" );
		m_Dropdown->AppendItem( "F_GRAY" );
		m_Dropdown->AppendItem( "F_HIGHLIGHT" );
		m_Dropdown->AppendItem( "F_ALPHA_TO_OVERLAY" );
		m_Dropdown->AppendItem( "F_GLOW" );
		m_Dropdown->AppendItem( "F_COLORIZE" );
		m_Dropdown->SetSelection( 0 );
		m_Dropdown->SetSelectionMessage( new Message( ID_SETFILTER ) );
		m_Dropdown->SetTarget( this );

		// An ImageView to show filter results:
		m_ImageView = new ImageView(bounds, "ImageView", new BitmapImage( *(( BitmapImage* )m_Img2) ));

		// Now it's time to display the images. First, let's create a bunch
		// of LayoutNodes, just to make the layout look fine...
		LayoutNode	*icon1node = new VLayoutNode("icon1");
		LayoutNode	*icon2node = new VLayoutNode("icon2");
		LayoutNode	*icon3node = new VLayoutNode("icon3");
		LayoutNode	*icon4node = new VLayoutNode("icon4");
		LayoutNode	*icon5node = new VLayoutNode("icon5");
		LayoutNode	*icon6node = new VLayoutNode("icon6");
		LayoutNode	*ddnode    = new VLayoutNode("dropdown");

		// Then we create ImageView objects, attach the Image objects to
		// them, and attach the ImageViews to the LayoutNodes:
		icon1node->AddChild(new ImageView(bounds, "ImageView", m_Img1), 1 );
		icon2node->AddChild(new ImageView(bounds, "ImageView", m_Img2), 1 );
		icon3node->AddChild(new ImageView(bounds, "ImageView", m_Img3), 1 );
		icon4node->AddChild(new ImageView(bounds, "ImageView", m_Img4, ImageView::NORMAL), 1 );
		icon5node->AddChild(new ImageView(bounds, "ImageView", m_Img5), 1 );
		icon6node->AddChild(new ImageView(bounds, "ImageView", m_Img6), 1 );

		// Some text below the images:
		icon1node->AddChild(new StringView(bounds, "str", "Disabled"));
		icon2node->AddChild(new StringView(bounds, "str", "Normal"));
		icon3node->AddChild(new StringView(bounds, "str", "Colorize+Glow"));
		icon4node->AddChild(new StringView(bounds, "str", "Overlay"));
		icon5node->AddChild(new StringView(bounds, "str", "Big"));
		icon6node->AddChild(new StringView(bounds, "str", "Small"));

		ddnode->AddChild( m_ImageView );
		ddnode->AddChild( new VLayoutSpacer("Spacer", 8, 8) );
		ddnode->AddChild( m_Dropdown );

		// Arrange the layout nodes add add them to the window:
		LayoutNode	*rootnode = new VLayoutNode("rootnode");
		LayoutNode	*iconnode = new HLayoutNode("icons");
		LayoutNode	*scalednode = new HLayoutNode("scaled_icons");
		iconnode->AddChild(icon1node);
		iconnode->AddChild(icon2node);
		iconnode->AddChild(icon3node);
		iconnode->AddChild(icon4node);
		scalednode->AddChild(ddnode);
		scalednode->AddChild(icon5node);
		scalednode->AddChild(icon6node);
		rootnode->AddChild(scalednode);
		rootnode->AddChild(iconnode);
		LayoutView	*rootview = new LayoutView(bounds, "rootview", NULL, CF_FOLLOW_ALL);
		rootview->SetRoot( rootnode );
		AddChild( rootview );
	} catch(errno_exception &e) {
		printf("%s\n", e.error_str());
	}
}

MainWin::~MainWin()
{
	// We have to delete the Images ourselves.
	if( m_Img1 ) delete m_Img1;
	if( m_Img2 ) delete m_Img2;
	if( m_Img3 ) delete m_Img3;
	if( m_Img4 ) delete m_Img4;
	if( m_Img5 ) delete m_Img5;
	if( m_Img6 ) delete m_Img6;
	if(m_ImageView->GetImage()) delete m_ImageView->GetImage();	
}

bool MainWin::OkToQuit(void)
{
	Application::GetInstance()->PostMessage(M_QUIT);
	return true;
}

