/******************************************************************************
 *
 * Copyright (c) 2000	TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer.
 *  
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 *	SolExplorer.cpp
 *
 *****************************************************************************/


// SOL++2000 
// 2000.07.01


#include <sol\ApplicationView.h>
#include <sol\Thread.h>
#include <sol\SplitPane.h>
#include <sol\IconedDirTree.h>
#include <sol\IconedFileList.h>
#include "resource.h"


/////////////////////////////////////////////////////////////////////////
// class DirScanner

class DirScanner	:public Thread {
	IconedDirTree*	treev;
public:
	DirScanner() { }
	void	setDirTree(IconedDirTree* tree) { 
			treev = tree;
	}
	void	run(); 
};

void DirScanner::run()
{
	char path[10];

	HTREEITEM item = (HTREEITEM)TVI_FIRST;

	char cdir[_MAX_PATH];
	::GetCurrentDirectory(sizeof(cdir), cdir);
	char* p = strchr(cdir, ':');
	if(p++) {
		*p = Zero;
	}

	DWORD d = ::GetLogicalDrives();
	for (int i = 0; i<26; i++) {
		if (d & 1) {
			sprintf(path, "%c:", 'A'+i);
			int id1 = 0;
			int id2 = 0;
			item = treev -> addItem(NULL, item, path);

			treev -> findDirectories(item, path, 0, 2);
			treev -> sortChildren(item, TRUE);

			if (strcmp(path, cdir) == 0) {
				treev -> expand(item, TVE_EXPAND);
			}
		}
		d = d >> 1;
	}
}

/////////////////////////////////////////////////////////////////////////
// class SolExplorer

class SolExplorer :public ApplicationView {
	SplitPane	   pane;
	DirScanner	   scanner;
	IconedDirTree  treev;
	IconedFileList files;

	long	close(Event& event);
	void	expanding(Action& action);
	void	selChanged(Action& action);

  public:
	SolExplorer(Application& applet, const char* name, Args& args);
};


SolExplorer::SolExplorer(Application& applet, const char* name, Args& args)
	:ApplicationView(applet, name, 
			args.set(XmNbackground, (ulong)(COLOR_BTNFACE+1))	)
{
	Args ar;
	ar.set(XmNdirection, SplitPane::HORIZONTAL);
	pane.create(this, "", ar);
	add(pane);

	ar.reset();
	ar.set(XmNexStyle, (ulong)WS_EX_CLIENTEDGE);
	ar.set(XmNstyle, (ulong)(TVS_HASBUTTONS|TVS_SHOWSELALWAYS|
						TVS_HASLINES|TVS_LINESATROOT));
	treev.create(&pane, "", ar);
	pane.add(&treev);

	ar.reset();
	ar.set(XmNexStyle, (ulong)WS_EX_CLIENTEDGE);
	ar.set(XmNstyle,  (ulong)LVS_SORTASCENDING | LVS_REPORT);
	files.create(&pane, "", ar);	
	pane.add(&files);
	pane.setSashPosition(200);

	treev.addCallback(XmNitemExpandingCallback, this, (Callback)&SolExplorer::expanding, NULL);
	
	treev.addCallback(XmNselChangedCallback, this, (Callback)&SolExplorer::selChanged, NULL);

	addCallback(XmNmenuCallback, IDM_EXIT, this, (Callback)&SolExplorer::exit, NULL);

	addEventHandler(WM_CLOSE, this, (Handler)&SolExplorer::close, NULL);

	restorePlacement();

	// Run DirScanner thread.
	scanner.setDirTree(&treev);
	scanner.start();
}

long SolExplorer::close(Event& event)
{
	// Never forget to call detachImageList method on Windows95/98.
	treev.detachImageList();
	files.detachImageList();

	savePlacement();
	return defaultProc(event);
}

void SolExplorer::expanding(Action& action)
{							 
	Event& event = action.getEvent();	
	NM_TREEVIEW* nmtreev = (NM_TREEVIEW*)event.getLParam();
	HTREEITEM htreeItem = nmtreev->itemNew.hItem;
	char dir[_MAX_PATH];
	dir[0] = Zero;
	// Get fullpathname of the selected node
	treev.getHierachy(htreeItem, dir, "\\");

	// Delete all children
	treev.deleteChildren(htreeItem);

	// Builde a tree for the subdirectory
	treev.findDirectories(htreeItem, dir, 0, 2);
	treev.sortChildren(htreeItem, TRUE);
}

void SolExplorer::selChanged(Action& action)
{
	Event& event = action.getEvent();
	NM_TREEVIEW* nmtr  = (NM_TREEVIEW*)event.getLParam();
	TV_ITEM tvItem     = nmtr -> itemNew;
	HTREEITEM hselItem = tvItem.hItem;

	char dir[MAX_PATH];
	dir[0] = Zero;
	treev.getHierachy(hselItem, dir, "\\");

	files.findFiles(dir);
	
	char title[MAX_PATH];
	sprintf(title, "%s - SolExplorer", dir);
	setText(title);
}

//	Program entry point.
void	Main(int argc, char** argv)
{
	const char* appClass = "SolExplorer";
	Application applet(appClass, argc, argv);

	Args args;
	
	SolExplorer explorer(applet, appClass, args);
	explorer.realize();

	applet.run();
}

