/*    
   Defrfact.c - calculate defragmentation factor.

   Copyright (C) 2000, 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 "bool.h"
#include "infofat.h"

/************************************************************
***                        GetDefragFactor
*************************************************************
*** Calculates the defragmentation factor.
*************************************************************/ 

int GetDefragFactor(RDWRHandle handle)
{
    unsigned long FileCount=0; /* the number of non zero files on disk */       
    unsigned long FreeClusters=0, UsedClusters=0, BadClusters=0;
    unsigned long Fragments=0;
    unsigned long LabelsInFat, clusterno;
    CLUSTER label;
    
    LabelsInFat = GetLabelsInFat(handle);
    if (!LabelsInFat) return 255;
    
    for (clusterno = 2; clusterno < LabelsInFat; clusterno++)
    {
        if (!GetNthCluster(handle, clusterno, &label))
           return 255;
           
        if (FAT_FREE(label))
           FreeClusters++;
        else if (FAT_BAD(label))
           BadClusters++;
        else 
           UsedClusters++;
           
        if (FAT_NORMAL(label) && (label > LabelsInFat))
        {
           return 255;
        }
    
        if (FAT_LAST(label))
        {
           FileCount++; 
        }
        else
        {
           if (label != clusterno + 1)
              Fragments++;
        }
    }
    
    if (UsedClusters == 0)
       return 100;              /* An empty volume is not fragmented */
  
    return (int) (100-(100 * Fragments / UsedClusters));    
}        