/*
  ==============================================================================

   This file is part of the mini timer
   Copyright 2005-10 by Satoshi Fujiwara.

   mini timer can be redistributed and/or modified under the terms of the
   GNU General Public License, as published by the Free Software Foundation;
   either version 2 of the License, or (at your option) any later version.

   mini timer is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with mini timer; if not, visit www.gnu.org/licenses or write to the
   Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
   Boston, MA 02111-1307 USA

  ==============================================================================
*/
#include "StdAfx.h"

#if _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif

#include "sf_windows.h"
#include "icon.h"
#include "toplevel_window.h"
#include "message_loop.h"
#include "sf_com.h"
#include "application.h"

#ifndef HINST_THISCOMPONENT
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
#endif



namespace sf {
#ifdef _DEBUG
  std::wstring application::app_id_(L"SF.MiniTimerDebug");
#else
  std::wstring application::app_id_(L"SF.MiniTimer");
#endif
application::application()
{
  instance_handle_ = HINST_THISCOMPONENT;
}

int application::execute(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
#ifdef _DEBUG
  ::_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);
#endif
  UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);
  std::wcout.imbue(std::locale(""));

  // 2重起動の防止
	SECURITY_DESCRIPTOR sd;
	InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
	SetSecurityDescriptorDacl(&sd, TRUE, 0, FALSE);	    
	SECURITY_ATTRIBUTES sec_attr;
	sec_attr.nLength = sizeof (sec_attr);
	sec_attr.lpSecurityDescriptor = &sd;
	sec_attr.bInheritHandle = TRUE; 
#ifdef _DEBUG 
  sf::handle_holder handle(::CreateMutex(&sec_attr, FALSE, _T("wintimer_mutex_debug")));
#else
  sf::handle_holder handle(::CreateMutex(&sec_attr, FALSE, _T("wintimer_mutex")));
#endif

	if(NULL == handle.get() || ::GetLastError() == ERROR_ALREADY_EXISTS)
	{
    return 0;
	}

  // COMの初期化
  sf::com_initialize init();

  // アプリケーションIDの登録
  sf::throw_if_err<application::exception>()(SetCurrentProcessExplicitAppUserModelID(app_id_.c_str()));
  
  // ウィンドウの作成
  sf::toplevel_window_ptr 
    window(
      sf::create_toplevel_window(
        std::wstring(L"ミニタイマー"),std::wstring(L"ミニタイマー")));
  
  // メッセージループの実行
  WPARAM ret = sf::run_message_loop()();
  return ret;
}

}

