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

// SearchDicomDlg.cpp : implementation file
//

#include "stdafx.h"
#include "clientUI.h"
#include "SearchDicomDlg.h"
#include "ListDicomDlg.h"


// SearchDicomDlg dialog

IMPLEMENT_DYNAMIC(SearchDicomDlg, CDialog)

SearchDicomDlg::SearchDicomDlg(DICOM_DBS dm_dbs, CWnd* pParent /*=NULL*/)
	: CDialog(SearchDicomDlg::IDD, pParent)
{
	int i;
	
	// Initialize bdb environment and database handles.
	m_dbs = dm_dbs;

	// Initialize the arrays of queried attributes and their value.
	for (i = 0; i < ATTRIBUTENUM;i++) {
		m_selAtt[i] = false;
		m_selValue[i] = "";
	}
}

SearchDicomDlg::~SearchDicomDlg()
{

}

void SearchDicomDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_COMBO_ATTRIBUTES, pComboAttribute);
	DDX_Control(pDX, IDC_COMBO_VALUE, pComboValue);
	DDX_Control(pDX, IDC_EDIT_QUERY, pEditQuery);
}

BOOL SearchDicomDlg::OnInitDialog()
{
	LPWSTR name;
	int i;
	
	CDialog::OnInitDialog();

	// Insert wide strings of all attributes' name into the combo box  
	// of attributes' name.
	for (i = 0; i < ATTRIBUTENUM;i++) {
		name = (convertCharToWchar(atts_name[i]));
		pComboAttribute.AddString(name);
		free(name);
	}
	
	return true;
}

BEGIN_MESSAGE_MAP(SearchDicomDlg, CDialog)
	ON_CBN_SELCHANGE(IDC_COMBO_ATTRIBUTES, 
	    &SearchDicomDlg::OnCbnSelchangeComboAttributes)
	ON_BN_CLICKED(IDC_BUTTON_ADD, &SearchDicomDlg::OnBnClickedButtonAdd)
	ON_BN_CLICKED(IDC_BUTTON_RESUME, 
	    &SearchDicomDlg::OnBnClickedButtonResume)
	ON_BN_CLICKED(IDC_BUTTON_SEARCH, 
	    &SearchDicomDlg::OnBnClickedButtonSearch)
END_MESSAGE_MAP()


// SearchDicomDlg message handlers

void SearchDicomDlg::OnCbnSelchangeComboAttributes()
{
	CString selString; // String of selected attribute.
	LPWSTR value;      // Wide string of query.
	char **keyString;  // String array of query.       
	int i;             // Iterate over all values of the selected 
			   // attribute.
	int indexed;       // Whether selected attribute is indexed.
	int number;        // Number of values of the selected attribute.
	int selIndex;      // Index of selected attribute in all attributes.
	int ret;

	// Initialize members.
	indexed = 0;
	keyString = new char*[50];
	ret = 0;
	
	// Get index of selected attribute in all attributes.
	selIndex  = pComboAttribute.GetCurSel();

	// Get string of selected attribute.
	pComboAttribute.GetLBText(selIndex, selString);
	
	// Clean the text in combo box of attribute value.
	pComboValue.ResetContent();

	// If the selected attribute is indexed, list all values on the 
	// attribute, that is all keys in its corresponding secondary index.
	if ((selString == "Patient's Name") || (selString == "Modality") || 
	    (selString == "Acquisition Date")) {
		// The current attribute is indexed.
		indexed = 1;
		if (selString == "Patient's Name")
			selIndex = PATIENTNAME;
		else if (selString == "Modality") 
			selIndex = MODALITY;
		else // (selString == "Acquisition Date")
			selIndex = ACQUISITIONDATE;
		
		ret = retrieve_attrs(&m_dbs, selIndex, keyString, &number);
		if (ret == 0) {
			// Add keys in the combo box of attribute value.
			for (i = 0; i < number;i++)  {
				// Convert the value to wide string.
				value = (convertCharToWchar(keyString[i]));
			
				// Insert into the combo box.
				pComboValue.AddString(value);
			
				// Free memory of the wide string.
				free(value);
			}
			
			// Free memory of keys.
			for (i = 0; i < number; i++)
				free(keyString[i]);
		}
	}
	
}


void SearchDicomDlg::OnBnClickedButtonAdd()
{
	CString attString;    // Queried attribute and value.
	CString queryString;  // Combination of queried attribute and value.
	CString valString;    // Queried value.
	int i;
	int att_idx;          // Index of selected attribute in all 
			      // attributes.
	int index;            // Index of selected attribute in combo box.
	wchar_t attName[20];  // Wide string of queried attribute name.
	wchar_t attValue[50]; // Wide string of queried attribute value.
	extern char atts_name[ATTRIBUTENUM][40];  
	        	      // The name of all attributes.
	char *a;              // Char string of queried attribute.
	
	// Initialize the query string.
	queryString = "";                
	
	// Get the index of selected attribute.
	index = pComboAttribute.GetCurSel(); 

	// Either click on any attribute name in the combo box or input one.
	if (index < 0) {
		// Get the text in the combo box.	
		pComboAttribute.GetWindowTextW((LPTSTR)attName, 20); 
		
		// Convert the text to char string and find its index in 
		// all attributes.
		a = convertWcharToChar(attName);
		att_idx = find_attributes_index(a);
		free(a);
		
		// If the input one is not a valid attribute name, give out 
		// warning and clear the combo box of attribute value.
		if (att_idx == -1) {
			MessageBox(TEXT("Sorry, no such attribute!"));
			pComboValue.ResetContent();
			return;
		}

		// If the input one is a valid attribute name, set the 
		// corresponding one in the boolean array to be true.
		m_selAtt[att_idx] = true;
	} else {
		// If any attribute in the combo box is being selected, get 
		// its name to get its index of all attributes and set the 
		// corresponding one in the boolean array to be true.
		pComboAttribute.GetLBText(index, attString);
		a = convertWcharToChar(attString.GetBuffer());
		att_idx = find_attributes_index(a);
		m_selAtt[att_idx] = true;
		free(a);
	}

	// Either click on any attribute value in the combo box or input 
	// one.
	index = pComboValue.GetCurSel(); 
	if (index < 0) {
		pComboValue.GetWindowTextW((LPTSTR)attValue, 50);
		m_selValue[att_idx] = attValue;
	} else {
		pComboValue.GetLBText(index, valString);
		m_selValue[att_idx] = valString;
	}

	// Get query string of all queried attributes and their values.
	for (i = 0; i < ATTRIBUTENUM; i++) {
		if (m_selAtt[i]) {
			queryString += atts_name[i];
			queryString += " = \"";
			queryString += m_selValue[i];
			queryString += "\"\r\n";
		}
	}

	// Set the content in edit box to be the query string.
	pEditQuery.SetWindowTextW(queryString);
}

void SearchDicomDlg::OnBnClickedButtonResume()
{
	// Clear the combo box of attribute name.
	pComboAttribute.SetWindowTextW(TEXT(""));
	
	// Clear the combo box of attribute value.
	pComboValue.ResetContent();
	
	// Clear the edit box of query.
	pEditQuery.SetWindowTextW(TEXT(""));
	
	// Reset the arrays of selected attributes and their values.
	for (int i = 0; i < ATTRIBUTENUM;i++) {
		m_selAtt[i] = false;
		m_selValue[i] = "";
	}
}

void SearchDicomDlg::OnBnClickedButtonSearch()
{
	DICOM_IMAGE list[MAX_NUMBER] = {}; 
				// DICOM result set.
	char *mulQuery[ATTRIBUTENUM] = {};  
	        		// Queried strings.
	int i;			// Iterate over all attributes.   
	int index;		// The last attribute.
	//int secIndex;		// The last indexed attribute.
	int number;		// The number of DICOMs in result set.
	int queriedNum;		// Number of queried attributes.
	int ret;

	// Initialize variables.
	index = ATTRIBUTENUM;
	ret = 0;

	for (i = 0, queriedNum= 0; i < ATTRIBUTENUM; i++) {
		if (m_selAtt[i]) {
			index = i;
			queriedNum++;
			mulQuery[i] = convertWcharToChar(
			    m_selValue[i].GetBuffer());	
		} 
	}

	// If non attribute is queried, give out the warning.
	if (queriedNum == 0) {
		MessageBox(TEXT("Please add query!"));
		return;
	}

	// If only one attribute is queried, see if it is indexed. If so, 
	// retrieve the DICOM in its corresponding secondary index. Unless,
	// retrieve it in primary database.
	if (queriedNum == 1) {
		ret = retrieve_dicom_with_oneattr(&m_dbs, index,
		    mulQuery[index], list, &number);
	} else {
		ret = retrieve_dicom_with_attrs(&m_dbs, mulQuery, 
		    list, &number);
	}
	
	// If there is no error, show the list of DICOMs in another dialog.
	if (ret != 0) 
		MessageBox(TEXT("Error retrieving DICOM! Please retry. "));
	else {
		ListDicomDlg listDlg(list, number, m_dbs, false);
		listDlg.DoModal();
	}

	// Free memory of char string. 
	for (i = 0, queriedNum= 0; i < ATTRIBUTENUM; i++) {
		if (mulQuery[i] != NULL) 
			free(mulQuery[i]);
	}

}

