/*    
   DfrgDrvr.c - driver for volume defragmentation.

   Copyright (C) 2002 Imre Leber

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

   If you have any questions, comments, suggestions, or fixes please
   email me at:  imre.leber@worldonline.be
*/

#include "fte.h"
#include "..\..\modlgate\expected.h"

BOOL DefragmentVolume(RDWRHandle handle,
                      BOOL (*select)(RDWRHandle handle,
                                     CLUSTER startfrom,
                                     CLUSTER* clustertoplace),
                      BOOL (*place)(RDWRHandle handle,
                                    CLUSTER clustertoplace,
                                    CLUSTER startfrom,
                                    CLUSTER* wentto))
{
     CLUSTER clustertoplace;
     CLUSTER cluster1 = 2, cluster2;

     unsigned long clustersindataarea;

     clustersindataarea = GetClustersInDataArea(handle);
     if (!clustersindataarea) return FALSE;

     for (;;)
     {
         if (QuerySaveState())
            return TRUE;        /* The user requested the process to stop */

	 switch (select(handle, cluster1, &clustertoplace))
         {
           case TRUE:
                /* Indicate how much of the disk that has already been optimized */
                IndicatePercentageDone(cluster1, clustersindataarea);
                
                switch (place(handle, clustertoplace, cluster1, &cluster2))
                {
                   case TRUE:
			cluster1 = cluster2;
                        CommitCache();
			break;

                   case FALSE: /* Disk full. */
                        CommitCache();
			return TRUE;

		   case FAIL:
                        CommitCache();
			return FALSE;
                }
                break;
                
           case FALSE: /* All done with defragmentation. */
                CommitCache();
                return TRUE;

	   case FAIL:  /* An error occured. */
                CommitCache();
		return FALSE;
         }
     }
}