using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace vclass.appsharing
{
	/// <summary>
	/// This class is responsible for capturing the screen...
	/// </summary>
	/// Author: Yavuz Gurcan
	/// created: 22/03/05
	
	class GDI32
	{
		[DllImport("GDI32.dll")]
		public static extern bool BitBlt(int hdcDest,int nXDest,int nYDest,
			int nWidth,int nHeight,int hdcSrc,
			int nXSrc,int nYSrc,int dwRop);
		[DllImport("GDI32.dll")]
		public static extern int CreateCompatibleBitmap(int hdc,int nWidth, 
			int nHeight);
		[DllImport("GDI32.dll")]
		public static extern int CreateCompatibleDC(int hdc);
		[DllImport("GDI32.dll")]
		public static extern bool DeleteDC(int hdc);
		[DllImport("GDI32.dll")]
		public static extern bool DeleteObject(int hObject);
		[DllImport("GDI32.dll")]
		public static extern int GetDeviceCaps(int hdc,int nIndex);
		[DllImport("GDI32.dll")]
		public static extern int SelectObject(int hdc,int hgdiobj);
	} 

		class User32
		{
			[DllImport("User32.dll")]
			public static extern int GetDesktopWindow();
			[DllImport("User32.dll")]
			public static extern int GetWindowDC(int hWnd);
			[DllImport("User32.dll")]
			public static extern int ReleaseDC(int hWnd,int hDC);
		}
 

		public class ScreenCapturer
		{
			private int leftX, topX, widthX, heightX;
			private String filePath = ".";

			public ScreenCapturer(){
			
			}

			public void setRectangle(int x, int y, int w, int h){
				leftX = x;
				topX = y;
				widthX = w;
				heightX = h;
			}

			public Image captureScreen(string fileName,ImageFormat imageFormat)
			{
				captureWindow(fileName, imageFormat, User32.GetWindowDC(User32.GetDesktopWindow()));
				return Image.FromFile(fileName);
			}

			public void captureWindow(string fileName,ImageFormat imageFormat, int hdcSrc)
			{
				int hdcDest = GDI32.CreateCompatibleDC(hdcSrc),
					hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc,
					GDI32.GetDeviceCaps(hdcSrc,8),GDI32.GetDeviceCaps(hdcSrc,10)); 
				GDI32.SelectObject(hdcDest,hBitmap);
				GDI32.BitBlt(hdcDest,0,0,GDI32.GetDeviceCaps(hdcSrc,8),
					GDI32.GetDeviceCaps(hdcSrc,10),
					hdcSrc,0,0,0x00CC0020);
				saveImageAs(hBitmap,fileName,imageFormat);
				cleanup(hBitmap,hdcSrc,hdcDest);
			}

			public void captureRectangle(string fileName,ImageFormat imageFormat)
			{
				int hdcSrc = User32.GetWindowDC(User32.GetDesktopWindow()),
					hdcDest = GDI32.CreateCompatibleDC(hdcSrc),
					hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc,
					widthX,heightX); 
				GDI32.SelectObject(hdcDest,hBitmap);
				GDI32.BitBlt(hdcDest, 0, 0, widthX, heightX,
					hdcSrc,leftX,topX,0x00CC0020);
				saveImageAs(hBitmap,fileName,imageFormat);
				cleanup(hBitmap,hdcSrc,hdcDest);
			}

			private void cleanup(int hBitmap,int hdcSrc,int hdcDest)
			{
				User32.ReleaseDC(User32.GetDesktopWindow(),hdcSrc);
				GDI32.DeleteDC(hdcDest);
				GDI32.DeleteObject(hBitmap);
			}      

			private void saveImageAs(int hBitmap,string fileName,ImageFormat imageFormat)
			{
				try
				{
					Bitmap image = 
						new Bitmap(Image.FromHbitmap(new IntPtr(hBitmap)),
						Image.FromHbitmap(new IntPtr(hBitmap)).Width,
						Image.FromHbitmap(new IntPtr(hBitmap)).Height);
					image.Save(fileName,imageFormat);
				}
				catch(Exception exc){
					Console.WriteLine("Exception occured " + exc.StackTrace + " " + exc.Message + " " + exc.Source);
				}
			}
		} 


}
