/*
 *  psychlops_widgets_osx.cpp
 *  Psychlops Standard Library (OSX)
 *
 *  Last Modified 2009/12/14 by Kenchi HOSOKAWA
 *  (C) 2009 Kenchi HOSOKAWA, Kazushi MARUYA and Takao SATO
 */


#include <AppKit/AppKit.h>
#include "../../../core/ApplicationInterfaces/psychlops_code_exception.h"
#include "../../../extension/standard/widgets/psychlops_widget.h"
#include "../psychlops_app_tweak_osx.h"

namespace Psychlops {
	namespace Widgets {
		
		
		namespace Dialog {
			
			void alert(std::string message)
			{
				boolean_t mouse_visible = CGCursorIsVisible();
				if(!mouse_visible) CGDisplayShowCursor( kCGDirectMainDisplay );
				NSString *str = [[ NSString alloc ] autorelease];
				[str initWithCString: message.c_str() ];
				NSAlert *alert = [[ NSAlert alertWithMessageText: @"Alert"
												   defaultButton: @"OK"
												 alternateButton: nil
													 otherButton: nil
									   informativeTextWithFormat: @"Notification" ] autorelease];
				if(!mouse_visible) CGDisplayHideCursor( kCGDirectMainDisplay );
				[ alert runModal ];
			}
			void alert(std::wstring message)
			{
				boolean_t mouse_visible = CGCursorIsVisible();
				if(!mouse_visible) CGDisplayShowCursor( kCGDirectMainDisplay );
				NSString *str = [[NSString alloc] autorelease];
				[ str initWithBytes: message.c_str()
							 length: message.length()
						   encoding: NSUnicodeStringEncoding ];
				NSAlert *alert = [[ NSAlert alertWithMessageText: @"Alert"
												   defaultButton: @"OK"
												 alternateButton: nil
													 otherButton: nil
									   informativeTextWithFormat: @"Notification" ] autorelease];
				[ alert runModal ];
				if(!mouse_visible) CGDisplayHideCursor( kCGDirectMainDisplay );
			}
			
			std::string getOpenFileName()
			{
				boolean_t mouse_visible = CGCursorIsVisible();
				if(!mouse_visible) CGDisplayShowCursor( kCGDirectMainDisplay );
				NSOpenPanel *openBox = [ NSOpenPanel openPanel ];
				//[ openBox setTitle: @"Select File" ];
				[ openBox setAllowsMultipleSelection: NO ];
				[ openBox runModal ];
				if(!mouse_visible) CGDisplayHideCursor( kCGDirectMainDisplay );
				const char *url = [ [ [ openBox URL ] path ] UTF8String ];
				std::string result;
				try {
					if(url!=0) result = url;
					else result.clear();
				}
				catch (std::exception e) {
					result.clear();
				}
				return result;
			}
			
		}	/*	<- namespace Dialog 	*/
		
		
		
		
		
		CloseButton::CloseButton()
		: Button(L"X", 20)
		{
			theme_type = Widgets::Theme::ALERT;
			Button::onClick = &exitApp;
			label.font.weight = Font::bold;
			label.fill = Color::white;
		}
		void CloseButton::exitApp()
		{
			if(AppState::shouldBeClose) exit(0);
			AppState::shouldBeClose = true;
		}
		
		MinimizeButton::MinimizeButton(Canvas &target)
		: Button(L"-", 20)
		{
			window = &target;
			arg = this;
			Button::onClickP = &minimizeApp;
			label.font.weight = Font::bold;
			label.fill = Color::white;
		}
		void MinimizeButton::minimizeApp(void *hwnd)
		{
			MinimizeButton *button = (MinimizeButton*)(hwnd);
			button->pushed_ = false;
			//		HWND window = Psychlops::DebugTweakTool::getRawWindowHandle(*(button->window));
			//		ShowWindow( window, SW_MINIMIZE );
		}
		
		
		TitleBar::TitleBar(Canvas &target)
		: mleft(Mouse::left), minimize(target)
		{
			Theme::initialize();
			area.set(target.getWidth()-85, 20);
			area.fill = Color::white;
			close.area.set(50, 20).setDatum(Point(target.getWidth()-55, 0));
			minimize.area.set(30, 20).setDatum(Point(target.getWidth()-85, 0));
			dragged_ = false;
		}
		TitleBar& TitleBar::draw(Drawable &target)
		{
			/*
			 Canvas *cnvs = dynamic_cast<Canvas*>(&target);
			 ::RECT rect;
			 TRACKMOUSEEVENT eventTrack;
			 
			 if(cnvs!=0) {
			 HWND window = Psychlops::DebugTweakTool::getRawWindowHandle(*cnvs);
			 ::POINT mousept;
			 if(mleft.pushed()) {
			 if(area.include(Mouse::position)) {
			 GetWindowRect(window, &rect);
			 begin_w.set(rect.left, rect.top);
			 begin_w_size.set(rect.right - rect.left, rect.bottom - rect.top);
			 begin_m = Mouse::uniPosition;
			 GetCursorPos(&mousept);
			 eventTrack.cbSize = sizeof(TRACKMOUSEEVENT);
			 eventTrack.dwFlags = TME_LEAVE;
			 eventTrack.hwndTrack = window;
			 eventTrack.dwHoverTime = 100;
			 TrackMouseEvent(&eventTrack);
			 DragDetect( window, mousept );
			 //ClipCursor( rect );
			 dragged_=true;
			 }
			 } else if(mleft.pressed() && dragged_) {
			 GetWindowRect(window, &rect);
			 Point p = (Point)Mouse::uniPosition - begin_m, np = p + begin_w;
			 MoveWindow(window, np.x, np.y, begin_w_size.x, begin_w_size.y, false);
			 eventTrack.cbSize = sizeof(TRACKMOUSEEVENT);
			 eventTrack.dwFlags = TME_LEAVE;
			 eventTrack.hwndTrack = window;
			 eventTrack.dwHoverTime = 100;
			 TrackMouseEvent(&eventTrack);
			 //GetCursorPos(&mousept);
			 //DragDetect( window, mousept );
			 //ClipCursor( rect );
			 } else if(mleft.released()) {
			 //ClipCursor( NULL );
			 dragged_ = false;
			 }
			 cnvs->drawImage(*(Theme::current.button_back), area);
			 cnvs->drawImage(*(Theme::current.horiz_grad), area);
			 }
			 */
			minimize.draw();
			close.draw();
			return *this;
		}
		
		
		
		//std::string SequentialScreenshot::bin_path = "C:\\Library\\Frameworks\\Psychlops.framework\\bin\\fmpeg.exe ";
		const SequentialScreenshot& SequentialScreenshot::save(std::string filename) {
/*
			std::stringstream command;
			char buf[256];
			for(int i=0; i<movie.size(); i++) {
				memset(buf, 0, 256);
				sprintf(buf, "snap%04d.png\0", i+1);
				movie[i]->save(directory+"/ScreenShots/"+buf);
			}
			command << bin_path << " -r 60 -y -i cap\\cap%04d.png -vcodec msmpeg4 " << filename;
			const char *lpArg = command.str().c_str();
			PROCESS_INFORMATION pi;
			STARTUPINFO si;
			ZeroMemory(&si,sizeof(si));
			si.cb=sizeof(si);
			CreateProcess(NULL,(LPTSTR)lpArg,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si, &pi);
			CloseHandle(pi.hThread);
			WaitForSingleObject(pi.hProcess,INFINITE);
			CloseHandle(pi.hProcess);
			clear();
			saved = true;
 */
			return *this;
		}
		
		
	}	/*	<- namespace Widgets 	*/
	namespace Figures {
		std::string Movie::bin_path = "ffmpeg ";
		const Movie& Movie::save(std::string filename)
		{
			//Process Manager Reference(Carbon) LaunchApplication
			//NSWorkspace(Cocoa) launchApplication
			std::string app_ = File::decodePath("%APP%");
			std::stringstream command;
			char buf[256];
			for(int i=0; i<frame.size(); i++) {
				memset(buf, 0, 256);
				sprintf(buf, "cap/snap%04d.png\0", i+1);
				frame[i]->save(buf);
			}
			command.str("");
			command << bin_path << " -i \"cap/snap%04d.png\" -loop_output 0 -pix_fmt rgb24 \"" << filename << "\"";
			NSString *str = [[NSString alloc] initWithUTF8String:command.str().c_str()];			
			[[NSWorkspace sharedWorkspace] launchApplication:str];
			[str release];
			return *this;
		}
	}
}	/*	<- namespace Psycholops 	*/
