/* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. */

// ListDicomDlg.cpp : implementation file
//

#include "stdafx.h"
#include "clientUI.h"
#include "ListDicomDlg.h"
#include "DisplayDicomDlg.h"
#include "DisplayAttDlg.h"

// ListDicomDlg dialog

IMPLEMENT_DYNAMIC(ListDicomDlg, CDialog)

ListDicomDlg::ListDicomDlg(DICOM_DBS dm_dbs,BOOL edit, CWnd* pParent /*=NULL*/)
	: CDialog(ListDicomDlg::IDD, pParent)
{
	DICOM_IMAGE list[MAX_NUMBER] = {};
	int number, ret, i;
	
        // Initialize private members except m_list.
	m_dbs = dm_dbs;
	m_edit = edit;
	m_list = NULL;

	// Retrieve all DICOMs from bdb into a list and return their number.
	ret = retrieve_all_dicom(&m_dbs, list, &number, 0);  
	
	// Initialize m_list from the retrieved DICOM list.
	m_list = (DICOM_IMAGE *)malloc(sizeof(DICOM_IMAGE) * number);
	for (i = 0; i < number; i++) {
		copy_dicom_image(&list[i], &m_list[i]);
		free_dicom_image(&list[i]);
	}
	m_number = number;
	
}

ListDicomDlg::ListDicomDlg(DICOM_IMAGE *list, int number, DICOM_DBS dm_dbs, 
    BOOL edit, CWnd* pParent /*=NULL*/)
	: CDialog(ListDicomDlg::IDD, pParent)
{
	// Initialize all private members.
	m_list = list;
	m_number = number;
	m_edit = edit;
	m_dbs = dm_dbs;
}

ListDicomDlg::~ListDicomDlg()
{
        // Release malloced memory in the DICOM list.
	for (int i = 0; i < m_number;i++)
		free_dicom_image(&(m_list[i]));
}

BOOL ListDicomDlg::OnInitDialog()
{
	LVCOLUMN lvColumn;             // Column in the list control.
	LVITEM lvItem;                 // Item in the list control.
	LPWSTR mdText, adText, pnText; // Wide string for listed attributes.
	int btCx, btCy, btX, btY;      // Rectangle of delete button.
	int listCtrlCx, listCtrlCy;    // Weight and height of list control.
	int i;
        	
        CDialog::OnInitDialog();
	
	// Position delete button and list control.
	btCx = 100;
	btCy = 20;
	btX = (GetSystemMetrics(SM_CXSCREEN) - 
	       GetSystemMetrics(SM_CXBORDER))/2 - 50;
	btY = GetSystemMetrics(SM_CYSCREEN) - 30;	
        listCtrlCx = GetSystemMetrics(SM_CXSCREEN) - 
                     GetSystemMetrics(SM_CXBORDER);
	listCtrlCy = (m_edit) ? GetSystemMetrics(SM_CYSCREEN) - 80: 
	                                GetSystemMetrics(SM_CYSCREEN) - 50;

	// Set the position of current dialog in the window.
	this->SetWindowPos(this, 0, 0, GetSystemMetrics(SM_CXFULLSCREEN), 
	    GetSystemMetrics(SM_CYFULLSCREEN), SWP_NOZORDER|SWP_NOMOVE);
	
	// Set the position of list control.
	pDicomList.SetWindowPos(this, 0, 0, listCtrlCx, listCtrlCy, 
	    SWP_NOZORDER|SWP_NOMOVE);
	
	// If DICOMs could be edited, all items in the list control should 
	// be prefixed with a checkbox to enable bulk delete and the delete
	// button should be visible. Otherwise, the delete button should be 
	// invisible.
	if (m_edit) {
		pDicomList.SetExtendedStyle(pDicomList.GetExtendedStyle()| 
		    LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT);
		pButtonDelete.SetWindowPos(this, btX, btY, btCx, btCy, 
		    SWP_NOZORDER|SWP_NOMOVE);
	} else {
		pButtonDelete.ShowWindow(SW_HIDE);
	}

	// The first column in the list control is the patient's name. 
	lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
	lvColumn.fmt = LVCFMT_LEFT;
	lvColumn.cx = listCtrlCx/3 + 30;
	lvColumn.pszText = (convertCharToWchar(atts_name[PATIENTNAME]));
	pDicomList.InsertColumn(0, &lvColumn);	
	free(lvColumn.pszText);

	// The second column in the list control is the modality.
	lvColumn.cx = listCtrlCx/3 - 30;
	lvColumn.pszText = (convertCharToWchar(atts_name[MODALITY]));
	pDicomList.InsertColumn(1, &lvColumn);
	free(lvColumn.pszText);

	// The third column in the list control is the acquisition date.
	lvColumn.cx = listCtrlCx/3;
	lvColumn.pszText = (convertCharToWchar(
	    atts_name[ACQUISITIONDATE]));
	pDicomList.InsertColumn(2, &lvColumn);
	free(lvColumn.pszText);
	
	// Insert DICOMs into list control. Every DICOM in list control is
	// represented by its acquisition date, patient's name and modality.
	lvItem.mask = LVIF_TEXT;	
	for (i = 0; i < m_number; i++) {
		// The new item is appended to the end of the list control.
		lvItem.iItem = i;
		lvItem.iSubItem = 0;
		
		// Insert acquisition date, patient's name and modality
		// value into the current item in the list control.
		mdText = (convertCharToWchar(m_list[i].modality));
		adText = (convertCharToWchar(m_list[i].acquisition_date));
		pnText = (convertCharToWchar(m_list[i].patient_name));
		lvItem.pszText = pnText;
		pDicomList.InsertItem(&lvItem);
		pDicomList.SetItemText(i, 1, mdText);
		pDicomList.SetItemText(i, 2, adText);
		
		// Free memory of wide strings.
		free(mdText);
		free(adText);
		free(pnText);
	}

	return TRUE; // return TRUE unless you set the focus to a control
	// EXCEPTION: OCX Property Pages should return FALSE

}

void ListDicomDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_DICOM_LIST, pDicomList);
	DDX_Control(pDX, IDC_BUTTON_DELETE, pButtonDelete);
}


BEGIN_MESSAGE_MAP(ListDicomDlg, CDialog)
	ON_NOTIFY(NM_CLICK, IDC_DICOM_LIST, 
	    &ListDicomDlg::OnNMClickDicomList)
	ON_BN_CLICKED(IDC_BUTTON_DELETE, 
	    &ListDicomDlg::OnBnClickedButtonDelete)
END_MESSAGE_MAP()



void ListDicomDlg::OnNMClickDicomList(NMHDR *pNMHDR, LRESULT *pResult)
{
	POSITION ps;	// The position of selected item in list control
	int nIndex;	// The index in the list control
	UINT nFlag;	// The flag of hitting in the list control
	
	// Get the current point being selected.
	DWORD dwPos = GetMessagePos();     
	CPoint point(LOWORD(dwPos), HIWORD(dwPos));   
	ScreenToClient(&point);   
 	pDicomList.HitTest(point, &nFlag);
	
	// If any valid item is selected, display its attributes and image.
	if (nFlag == LVHT_ONITEMLABEL) {
		// Get the selected position in list control.
		ps = pDicomList.GetFirstSelectedItemPosition();
		// Get the index of selected item.
		nIndex = pDicomList.GetNextSelectedItem(ps);
		
		// If DICOM_IMAGE is complete, display its attributes and
		// image in another dialog. Unless, retrieve the DICOM_IMAGE
		// from bdb according to its id and display its attributes
		// and image in another dialog.
		if (m_list[nIndex].id != 0) {
			DisplayAttDlg displayAttDlg(m_list[nIndex].id, 
			    m_edit, &m_dbs);
			displayAttDlg.DoModal();
		} else {
			DisplayAttDlg displayAttDlg(&(m_list[nIndex]), 
			    m_edit, &m_dbs);
			displayAttDlg.DoModal();
		}
	}
}

void ListDicomDlg::OnBnClickedButtonDelete()
{
	//DICOM_IMAGE image;
	int ret;
	
	// Delete all selected DICOMs. Delete one or more than one DICOM  
	// whose checkbox is selected.
	for(int i = 0; i < m_number;i++) {
		if (pDicomList.GetItemState(i, LVIS_SELECTED) == 
		    LVIS_SELECTED || pDicomList.GetCheck(i)) {
			
			// Delete the selected DICOM with its ID.
			ret = delete_dicom_with_id(&m_dbs, m_list[i].id);

			pDicomList.DeleteItem(i);

		}
	} 
}
