/******************************************************************************
 JXChoosePathDialog.cc

	Clients must call BuildWindow() after constructing the object.
	Derived classes must override BuildWindow() and call SetObjects()
	at the end of their implementation.

	BASE CLASS = JXCSFDialogBase

	Copyright © 1996 by John Lindal. All rights reserved.

 ******************************************************************************/

#include <JXChoosePathDialog.h>
#include <JXUNIXDirTable.h>
#include <JUNIXDirInfo.h>
#include <JUNIXDirEntry.h>
#include <JXNewDirButton.h>

#include <JXWindow.h>
#include <JXStaticText.h>
#include <JXTextButton.h>
#include <JXTextCheckbox.h>
#include <JXPathInput.h>
#include <JXPathHistoryMenu.h>
#include <JXScrollbarSet.h>
#include <jXGlobals.h>

#include <JTableSelection.h>
#include <JUserNotification.h>
#include <JString.h>
#include <jDirUtil.h>
#include <jAssert.h>

/******************************************************************************
 Constructor

 ******************************************************************************/

JXChoosePathDialog::JXChoosePathDialog
	(
	JXDirector*			supervisor,
	JUNIXDirInfo*		dirInfo,
	const JCharacter*	fileFilter,
	const JBoolean		selectOnlyWritable
	)
	:
	JXCSFDialogBase(supervisor, dirInfo, fileFilter),
	itsSelectOnlyWritableFlag( selectOnlyWritable )
{
}

/******************************************************************************
 Destructor

 ******************************************************************************/

JXChoosePathDialog::~JXChoosePathDialog()
{
}

/******************************************************************************
 BuildWindow

 ******************************************************************************/

void
JXChoosePathDialog::BuildWindow
	(
	const JCharacter* message
	)
{
// begin JXLayout

    JXWindow* window = new JXWindow(this, 310,340, "");
    assert( window != NULL );
    SetWindow(window);

    itsOpenButton =
        new JXTextButton("Open", window,
                    JXWidget::kFixedRight, JXWidget::kFixedBottom, 219,249, 72,22);
    assert( itsOpenButton != NULL );
    itsOpenButton->SetShortcuts("^M");

    JXTextButton* cancelButton =
        new JXTextButton("Cancel", window,
                    JXWidget::kFixedRight, JXWidget::kFixedBottom, 220,280, 70,20);
    assert( cancelButton != NULL );
    cancelButton->SetShortcuts("^[");

    JXTextButton* homeButton =
        new JXTextButton("Home", window,
                    JXWidget::kFixedRight, JXWidget::kFixedBottom, 250,110, 40,20);
    assert( homeButton != NULL );
    homeButton->SetShortcuts("#H");

    JXStaticText* pathLabel =
        new JXStaticText("Path:", window,
                    JXWidget::kFixedLeft, JXWidget::kFixedBottom, 20,20, 40,20);
    assert( pathLabel != NULL );

    JXScrollbarSet* scrollbarSet =
        new JXScrollbarSet(window,
                    JXWidget::kHElastic, JXWidget::kFixedBottom, 20,110, 180,190);
    assert( scrollbarSet != NULL );

    itsSelectButton =
        new JXTextButton("Here", window,
                    JXWidget::kFixedRight, JXWidget::kFixedBottom, 220,220, 70,20);
    assert( itsSelectButton != NULL );
    itsSelectButton->SetShortcuts("#E");

    JXPathInput* pathInput =
        new JXPathInput(window,
                    JXWidget::kHElastic, JXWidget::kFixedBottom, 60,20, 200,20);
    assert( pathInput != NULL );

    JXTextCheckbox* showHiddenCB =
        new JXTextCheckbox("Show hidden files", window,
                    JXWidget::kFixedLeft, JXWidget::kFixedBottom, 60,80, 130,20);
    assert( showHiddenCB != NULL );
    showHiddenCB->SetShortcuts("#S");

    JXStaticText* filterLabel =
        new JXStaticText("Filter:", window,
                    JXWidget::kFixedLeft, JXWidget::kFixedBottom, 20,50, 40,20);
    assert( filterLabel != NULL );

    JXInputField* filterInput =
        new JXInputField(window,
                    JXWidget::kHElastic, JXWidget::kFixedBottom, 60,50, 200,20);
    assert( filterInput != NULL );

    JXStaticText* explanText =
        new JXStaticText("Go into the directory and click on Here.", window,
                    JXWidget::kFixedLeft, JXWidget::kFixedBottom, 20,310, 270,20);
    assert( explanText != NULL );

    JXPathHistoryMenu* pathHistory =
        new JXPathHistoryMenu(1, "", window,
                    JXWidget::kFixedRight, JXWidget::kFixedBottom, 260,20, 30,20);
    assert( pathHistory != NULL );

    JXStringHistoryMenu* filterHistory =
        new JXStringHistoryMenu(1, "", window,
                    JXWidget::kFixedRight, JXWidget::kFixedBottom, 260,50, 30,20);
    assert( filterHistory != NULL );

    JXTextButton* upButton =
        new JXTextButton("Up", window,
                    JXWidget::kFixedRight, JXWidget::kFixedBottom, 220,110, 30,20);
    assert( upButton != NULL );
    upButton->SetShortcuts("#U");

    JXNewDirButton* newDirButton =
        new JXNewDirButton(window,
                    JXWidget::kFixedRight, JXWidget::kFixedBottom, 220,140, 70,20);
    assert( newDirButton != NULL );

// end JXLayout

	SetObjects(scrollbarSet, pathLabel, pathInput, pathHistory,
			   filterLabel, filterInput, filterHistory,
			   itsOpenButton, itsSelectButton, cancelButton,
			   upButton, homeButton,
			   newDirButton, showHiddenCB, message);
}

/******************************************************************************
 SetObjects (protected)

 ******************************************************************************/

void
JXChoosePathDialog::SetObjects
	(
	JXScrollbarSet*			scrollbarSet,
	JXStaticText*			pathLabel,
	JXPathInput*			pathInput,
	JXPathHistoryMenu*		pathHistory,
	JXStaticText*			filterLabel,
	JXInputField*			filterInput,
	JXStringHistoryMenu*	filterHistory,
	JXTextButton*			openButton,
	JXTextButton*			selectButton,
	JXTextButton*			cancelButton,
	JXTextButton*			upButton,
	JXTextButton*			homeButton,
	JXNewDirButton*			newDirButton,
	JXTextCheckbox*			showHiddenCB,
	const JCharacter*		message
	)
{
	itsOpenButton   = openButton;
	itsSelectButton = selectButton;

	(scrollbarSet->GetWindow())->SetTitle("Choose directory");

	SetButtons(itsSelectButton, cancelButton);
	JXCSFDialogBase::SetObjects(
		scrollbarSet, pathLabel, pathInput, pathHistory,
		filterLabel, filterInput, filterHistory,
		itsOpenButton, upButton, homeButton, newDirButton,
		showHiddenCB, message);

	JXUNIXDirTable* fileBrowser = GetFileBrowser();
	fileBrowser->AllowSelectFiles(kFalse, kFalse);
	UpdateDisplay();

	ListenTo(itsOpenButton);
	ListenTo(fileBrowser);
	ListenTo(&(fileBrowser->GetTableSelection()));
}

/******************************************************************************
 Receive (virtual protected)

 ******************************************************************************/

void
JXChoosePathDialog::Receive
	(
	JBroadcaster*	sender,
	const Message&	message
	)
{
	JXUNIXDirTable* fileBrowser = GetFileBrowser();

	if (sender == itsOpenButton && message.Is(JXButton::kPushed))
		{
		JXPathInput* pathInput    = GetPathInput();
		JXInputField* filterInput = GetFilterInput();

		if (pathInput->HasFocus())
			{
			GoToItsPath();
			}
		else if (filterInput->HasFocus())
			{
			AdjustFilter();
			}
		else if (fileBrowser->HasFocus())
			{
			fileBrowser->GoToSelectedDirectory();
			}
		}

	else if (sender == fileBrowser &&
			 (message.Is(JXWidget::kGotFocus) ||
			  message.Is(JXWidget::kLostFocus)))
		{
		UpdateDisplay();
		}

	else
		{
		if (sender == &(fileBrowser->GetTableSelection()))
			{
			UpdateDisplay();
			}

		JXCSFDialogBase::Receive(sender, message);
		}
}

/******************************************************************************
 OKToDeactivate (virtual protected)

 ******************************************************************************/

JBoolean
JXChoosePathDialog::OKToDeactivate()
{
	if (!JXCSFDialogBase::OKToDeactivate())
		{
		return kFalse;
		}
	else if (Cancelled())
		{
		return kTrue;
		}

	else if ((GetPathInput())->HasFocus() && !GoToItsPath())
		{
		return kFalse;
		}

	else if (itsSelectOnlyWritableFlag && !JDirectoryWritable(GetPath()))
		{
		(JGetUserNotification())->ReportError("You must select a writable directory.");
		return kFalse;
		}
	else
		{
		return kTrue;
		}
}

/******************************************************************************
 UpdateDisplay (virtual protected)

 ******************************************************************************/

void
JXChoosePathDialog::UpdateDisplay()
{
	JXCSFDialogBase::UpdateDisplay();

	if (itsSelectOnlyWritableFlag && !(GetDirInfo())->IsWritable())
		{
		itsSelectButton->Deactivate();
		}
	else
		{
		itsSelectButton->Activate();
		}

	JXUNIXDirTable* dirTable = GetFileBrowser();
	if (dirTable->HasFocus() && !dirTable->HasSelection())
		{
		itsOpenButton->Deactivate();
		}
	else
		{
		itsOpenButton->Activate();
		}
}
