// AVRusbTemperDlg.cpp : implementation file
//

#include "stdafx.h"
#include "AVRusbTemper.h"
#include "AVRusbTemperDlg.h"
#include "usb.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


#define BTN_X	0
#define BTN_Y	0

const int IDB_LIST[10]={IDB_BMP_NUM_0,IDB_BMP_NUM_1,IDB_BMP_NUM_2,IDB_BMP_NUM_3,IDB_BMP_NUM_4,
	IDB_BMP_NUM_5,IDB_BMP_NUM_6,IDB_BMP_NUM_7,IDB_BMP_NUM_8,IDB_BMP_NUM_9};


usb_dev_handle      *handle = NULL;
unsigned char       buffer[8];
int                 nBytes;

int usbOpenDevice(usb_dev_handle **device, int vendor, int product)
{
	struct usb_bus      *bus;
	struct usb_device   *dev;
	usb_dev_handle      *handle = NULL;
	int                 errorCode = USB_ERROR_NOTFOUND;
	static int          didUsbInit = 0;

    if(!didUsbInit)
	{
        didUsbInit = 1;
        usb_init();
    }
    usb_find_busses();
    usb_find_devices();
    for(bus=usb_get_busses(); bus; bus=bus->next)
	{
        for(dev=bus->devices; dev; dev=dev->next)
		{
            if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product)
			{
				//AfxMessageBox("found");
                handle = usb_open(dev); /* we need to open the device in order to query strings */
                if(!handle)
				{
                    errorCode = USB_ERROR_ACCESS;
                    AfxMessageBox("Warning: cannot open USB device");
                    continue;
                }
                
            }
        }
        if(handle)
            break;
    }
    if(handle != NULL)
	{
        errorCode = 0;
        *device = handle;
    }
    return errorCode;
}

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAVRusbTemperDlg dialog

CAVRusbTemperDlg::CAVRusbTemperDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CAVRusbTemperDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CAVRusbTemperDlg)
	m_tem_alarm = 0;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CAVRusbTemperDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAVRusbTemperDlg)
	DDX_Control(pDX, IDC_EDIT_TMP, m_tmp_str);
	DDX_Text(pDX, IDC_EDIT_TMP, m_tem_alarm);
	DDV_MinMaxUInt(pDX, m_tem_alarm, 0, 99);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAVRusbTemperDlg, CDialog)
	//{{AFX_MSG_MAP(CAVRusbTemperDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_BTN_UP, OnBtnUp)
	ON_EN_CHANGE(IDC_EDIT_TMP, OnChangeEditTmp)
	ON_BN_CLICKED(IDC_BTN_DOWN, OnBtnDown)
	ON_BN_CLICKED(IDC_BTN_MODE, OnBtnMode)
	ON_MESSAGE(WM_SHOWTASK,onShowTask)
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAVRusbTemperDlg message handlers

BOOL CAVRusbTemperDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	RECT rect;
	SystemParametersInfo(SPI_GETWORKAREA,0,&rect,SPIF_SENDCHANGE);
	::SetWindowPos(m_hWnd,HWND_TOPMOST,rect.right-170,rect.bottom-170 ,166,170,0);

	CWnd * CWndButton = GetDlgItem(IDC_BTN_NUM_1);
	CWndButton->MoveWindow(BTN_X,BTN_Y,45,82);
	btn_1.SubclassDlgItem(IDC_BTN_NUM_1,this);
	btn_1.SetBitmaps(IDB_BMP_NUM_0,RGB(255,255,255));

	CWndButton = GetDlgItem(IDC_BTN_NUM_SOLID);
	CWndButton->MoveWindow(BTN_X+45,BTN_Y,13,82);
	btn_solid.SubclassDlgItem(IDC_BTN_NUM_SOLID,this);
	btn_solid.SetBitmaps(IDB_BMP_SOLID,RGB(255,255,255));

	CWndButton = GetDlgItem(IDC_BTN_NUM_2);
	CWndButton->MoveWindow(BTN_X+58,BTN_Y,45,82);
	btn_2.SubclassDlgItem(IDC_BTN_NUM_2,this);
	btn_2.SetBitmaps(IDB_BMP_NUM_0,RGB(255,255,255));

	CWndButton = GetDlgItem(IDC_BTN_NUM_POINT);
	CWndButton->MoveWindow(BTN_X+103,BTN_Y,13,82);
	btn_point.SubclassDlgItem(IDC_BTN_NUM_POINT,this);
	btn_point.SetBitmaps(IDB_BMP_POINT,RGB(255,255,255));

	CWndButton = GetDlgItem(IDC_BTN_NUM_3);
	CWndButton->MoveWindow(BTN_X+116,BTN_Y,45,82);
	btn_3.SubclassDlgItem(IDC_BTN_NUM_3,this);
	btn_3.SetBitmaps(IDB_BMP_NUM_0,RGB(255,255,255));


	CWndButton = GetDlgItem(IDC_BTN_UP);
	CWndButton->MoveWindow(BTN_X+116+45-16,BTN_Y+100,16,16);
	btn_up.SubclassDlgItem(IDC_BTN_UP,this);
	btn_up.SetBitmaps(IDB_BMP_UP,RGB(255,255,255));

	CWndButton = GetDlgItem(IDC_BTN_DOWN);
	CWndButton->MoveWindow(BTN_X+116+45-16,BTN_Y+116,16,16);
	btn_down.SubclassDlgItem(IDC_BTN_DOWN,this);
	btn_down.SetBitmaps(IDB_BMP_DOWN,RGB(255,255,255));

	CWndButton = GetDlgItem(IDC_EDIT_TMP);
	CWndButton->SetWindowText("40");
	UpdateData(TRUE);
	CWndButton->MoveWindow(BTN_X+116+45-16-40,BTN_Y+100,40,32);

	CWndButton = GetDlgItem(IDC_BTN_MODE);
	CWndButton->MoveWindow(BTN_X+10,BTN_Y+100,80,32);
	btn_mode.SubclassDlgItem(IDC_BTN_MODE,this);
	btn_mode.SetColor(CButtonST::BTNST_COLOR_BK_IN, RGB(208,208,208));
	btn_mode.SetColor(CButtonST::BTNST_COLOR_FG_IN, RGB(0,255,0));

	//MoveWindow(500,300,166,170);

	AlarmFlag=0;
	ModeFlag=0;
	DisplyNum(0);

	if(handle==NULL)
	{
		int error=usbOpenDevice(&handle,USBDEV_SHARED_VENDOR,USBDEV_SHARED_PRODUCT);
		if(error>0)
		{
			AfxMessageBox("打开usb设备出错！");
			return TRUE;
		}
	}
	if(handle)
	{
			usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, 
			SET_MOTO_SPEED, 255, 0, (char *)buffer, sizeof(buffer), 5000);
	}
	SetTimer(3,3000,NULL);
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CAVRusbTemperDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CAVRusbTemperDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CAVRusbTemperDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CAVRusbTemperDlg::DisplyNum(int num)
{
	int tmp[3],i;
	if(num >= 1000)
	{
		num %= 1000;
	}
	for(i=0;i<=2;i++)
	{
		tmp[2-i] = num%10;
		num = (int)(num/10);
	}
	if(tmp[0]>0)
	{
		btn_1.SetBitmaps(IDB_LIST[tmp[0]],RGB(255,255,255));
		btn_2.SetBitmaps(IDB_LIST[tmp[1]],RGB(255,255,255));
		btn_3.SetBitmaps(IDB_LIST[tmp[2]],RGB(255,255,255));
	}
	else /*if(tmp[1]>0)*/
	{
		btn_1.SetBitmaps(IDB_BMP_N,RGB(255,255,255));
		btn_2.SetBitmaps(IDB_LIST[tmp[1]],RGB(255,255,255));
		btn_3.SetBitmaps(IDB_LIST[tmp[2]],RGB(255,255,255));
	}
	/*else
	{
		btn_1.SetBitmaps(IDB_BMP_N,RGB(255,255,255));
		btn_2.SetBitmaps(IDB_BMP_N,RGB(255,255,255));
		btn_3.SetBitmaps(IDB_LIST[tmp[2]],RGB(255,255,255));
	}*/
}

void CAVRusbTemperDlg::OnCancel() 
{
	// TODO: Add extra cleanup here
	
	CDialog::OnCancel();
}

void CAVRusbTemperDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	int tmp_cur,tmp_old=0;
	if(handle)
	{
		nBytes = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, 
			GET_CUR_TMP, 0, 0, (char *)buffer, sizeof(buffer), 5000);
		if(nBytes>1)
		{
			tmp_cur=(int)buffer[0];
			tmp_cur <<= 8;
			tmp_cur += buffer[1];
			tmp_cur=(int)(tmp_cur*0.625);
			if(tmp_cur != tmp_old)
			{
				tmp_old = tmp_cur;
				DisplyNum(tmp_old);
				if(tmp_old >= (int)(m_tem_alarm*10) && ModeFlag==0)
				{
					AlarmFlag=1;
					CWnd *wnd=GetDlgItem(IDC_BTN_MODE);
					btn_mode.SetColor(CButtonST::BTNST_COLOR_FG_IN, RGB(255,0,0));
					wnd->SetWindowText("高温");
				}
				else if(tmp_old <= (int)(m_tem_alarm*10) && ModeFlag==0)
				{
					AlarmFlag=0;
					CWnd *wnd=GetDlgItem(IDC_BTN_MODE);
					btn_mode.SetColor(CButtonST::BTNST_COLOR_FG_IN, RGB(0,255,0));
					wnd->SetWindowText("正常");
				}
			}
		}
	}
	CDialog::OnTimer(nIDEvent);
}

void CAVRusbTemperDlg::OnBtnUp() 
{
	// TODO: Add your control notification handler code here
	if(m_tem_alarm<99)
	{
		CString str;
		m_tem_alarm++;
		str.Format("%d",m_tem_alarm);
		CWnd *wnd=GetDlgItem(IDC_EDIT_TMP);
		wnd->SetWindowText(str);
		UpdateData(TRUE);
	}
}

void CAVRusbTemperDlg::OnChangeEditTmp() 
{
	// TODO: If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CDialog::OnInitDialog()
	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.
	
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	
}

void CAVRusbTemperDlg::OnBtnDown() 
{
	// TODO: Add your control notification handler code here
	if(m_tem_alarm>0)
	{
		CString str;
		m_tem_alarm--;
		str.Format("%d",m_tem_alarm);
		CWnd *wnd=GetDlgItem(IDC_EDIT_TMP);
		wnd->SetWindowText(str);
		UpdateData(TRUE);
	}
}

void CAVRusbTemperDlg::OnBtnMode() 
{
	// TODO: Add your control notification handler code here
	if(!ModeFlag)
	{
		CWnd *wnd=GetDlgItem(IDC_BTN_MODE);
		wnd->SetWindowText("静音");
		btn_mode.SetColor(CButtonST::BTNST_COLOR_FG_IN, RGB(0,0,255));
		if(handle)
		{
			usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, 
			SET_MOTO_SPEED, 100, 0, (char *)buffer, sizeof(buffer), 5000);
		}
		ModeFlag=1;
	}
	else
	{
		CWnd *wnd=GetDlgItem(IDC_BTN_MODE);
		if(AlarmFlag)
		{
			btn_mode.SetColor(CButtonST::BTNST_COLOR_FG_IN, RGB(255,0,0));
			wnd->SetWindowText("高温");
		}
		else
		{
			btn_mode.SetColor(CButtonST::BTNST_COLOR_FG_IN, RGB(0,255,0));
			wnd->SetWindowText("正常");
		}
		if(handle)
		{
			usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, 
			SET_MOTO_SPEED, 255, 0, (char *)buffer, sizeof(buffer), 5000);
		}
		ModeFlag=0;
	}
}

void CAVRusbTemperDlg::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	switch(nType)
	{
	case SIZE_MINIMIZED:
		 {
			 toTray(TRUE);
			 break;
		 }
	}
	
}

void CAVRusbTemperDlg::toTray(BOOL show)
{
	NOTIFYICONDATA pnid;
    pnid.cbSize=(DWORD)sizeof(NOTIFYICONDATA);//该结构体大小
    pnid.hWnd=m_hWnd;    //窗口句柄
    pnid.uID=(UINT)IDR_MAINFRAME;      //图标句柄
    pnid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP ;  /*图标有效|自定义消息有效|鼠标指向显示文字有效*/
    pnid.uCallbackMessage=WM_SHOWTASK;//自定义的消息名称
    pnid.hIcon=m_hIcon;         //图标句柄
    strcpy(pnid.szTip,"AVRusbTemper");//鼠标指到那所显示的文字
    if(show)
    {
        Shell_NotifyIcon(NIM_ADD,&pnid);//在托盘区添加图标
        ShowWindow(SW_HIDE);//隐藏主窗口    
    }
    else
    {
        Shell_NotifyIcon(NIM_DELETE,&pnid);//删除托盘图标
		ShowWindow(SW_SHOW);//显示主窗口
    }

}

LRESULT CAVRusbTemperDlg::onShowTask(WPARAM wParam,LPARAM lParam) 
//wParam接收的是图标的ID，而lParam接收的是鼠标的行为 
{ 
	if(wParam != IDR_MAINFRAME)
	{
		return 1; 
	}
	switch(lParam) 
	{ 
		case WM_LBUTTONDBLCLK://双击左键的处理 
		{ 
			toTray(FALSE); 
		} 
		break; 
	} 
	return 0; 
}
