
//--------------------------------------------------------------------
// Class FileAttribute
//
// Purpose  : handle all file attributes
//--------------------------------------------------------------------

import java.util.Date;
import java.util.Vector;
import java.util.StringTokenizer;

public class FileAttribute
{
	public String type;
	public String fileName;
	public String linkName;
	public int linkIndex;
	public int size;
	public long lastModified;
	public long lastAccessed;
	public int hardLinkCount;

	private Vector blockNo;


//--------------------------------------------------------------------
// Contructor for FileAttribute
//
// Input	: fileEntry, newFile(true or false)
//          : fileEntry form <type fileName linkName linkIndex size lastModified 
//            lastAccesssed hardLinkCount blockNo0 blockNo1 ... \n> 
// Output   : None
// Purpose  : contructing the fileAttribute
//--------------------------------------------------------------------
	
	public FileAttribute (String fileEntry, boolean newFile)
	{
		StringTokenizer entry = new StringTokenizer(fileEntry);

		if (newFile)
		{
			type = entry.nextToken();
			fileName = entry.nextToken();
			linkName = entry.nextToken();
			linkIndex = Integer.parseInt(entry.nextToken());

			// add blockNo in to vector
			blockNo = new Vector();
			while (entry.countTokens() > 0) 
				blockNo.addElement(new Integer(Integer.parseInt(entry.nextToken())));
			size = 0;
			lastModified = System.currentTimeMillis();
			lastAccessed = System.currentTimeMillis();
			hardLinkCount = 1;
		}
		else
		{
			type = entry.nextToken();
			fileName = entry.nextToken();
			linkName = entry.nextToken();
			linkIndex = Integer.parseInt(entry.nextToken());
			size = Integer.parseInt(entry.nextToken());
			lastModified = Long.parseLong(entry.nextToken());
			lastAccessed = Long.parseLong(entry.nextToken());
			hardLinkCount = Integer.parseInt(entry.nextToken());

			// add blockNo in to vector
			blockNo = new Vector();
			while (entry.countTokens() > 0) 
				blockNo.addElement(new Integer(Integer.parseInt(entry.nextToken())));
		}
	}


//--------------------------------------------------------------------
// Method getContent
//
// Input	: None
// Output   : file attribute content
// Purpose  : to get file attribute Content
//--------------------------------------------------------------------

	public String getContent ()
	{
		String fileEntry = type + " "
							+ fileName + " "
							+ linkName + " "
							+ Integer.toString(linkIndex) + " "
							+ Integer.toString(size) + " "
							+ Long.toString(lastModified) + " "
							+ Long.toString(lastAccessed) + " "
							+ Integer.toString(hardLinkCount) + " ";

		int noOfBlocks = blockNo.size();
		for ( int i = 0 ; i < noOfBlocks ; i++ )
			fileEntry += blockNo.elementAt(i).toString() + " ";

		return fileEntry;
	}


//--------------------------------------------------------------------
// Method getDescr
//
// Input	: None
// Output   : file attribute description
// Purpose  : to get file attribute description for debugging
//--------------------------------------------------------------------

	public String getDescr ()
	{
		StringTokenizer tmp = new StringTokenizer
			((new Date(lastModified)).toLocaleString());

		String lm = new String();
		String tmpString;

		// date
		tmpString = tmp.nextToken();
		lm += (tmpString.length() < 9) ? " 0" + tmpString : " " + tmpString; 

		// time
		tmpString = tmp.nextToken();
		lm += (tmpString.length() < 8) ? " 0" + tmpString : " " + tmpString;

		// am/pm
		tmpString = tmp.nextToken();
		lm += " " + tmpString;

		String la = new String(); 
		tmp = new StringTokenizer
			((new Date(lastAccessed)).toLocaleString());

		// date
		tmpString = tmp.nextToken();
		la += (tmpString.length() < 9) ? " 0" + tmpString : " " + tmpString;

		// time
		tmpString = tmp.nextToken();
		la += (tmpString.length() < 8) ? " 0" + tmpString : " " + tmpString;

		// am/pm
		tmpString = tmp.nextToken();
		la += " " + tmpString;

		String hl = Integer.toString(hardLinkCount);
		if (hl.length() < 2) hl = " " + hl;

		return (type + " " + lm + " " + la + " " + hl + " ");
	}


//--------------------------------------------------------------------
// Method getNoOfBlocks
//
// Input	: None
// Output   : noOfBlocks
// Purpose  : to get the number of blocks that the file takes
//--------------------------------------------------------------------

	public int getNoOfBlocks ()
	{
		return blockNo.size();
	}


//--------------------------------------------------------------------
// Method getBlockAt
//
// Input	: the logical block no
// Output   : the physical block no to the disk
// Purpose  : map logical block number with physical block number 
//--------------------------------------------------------------------

	public int getBlockAt (int blockNoIndex)
	{
		return ((Integer)(blockNo.elementAt(blockNoIndex))).intValue();
	}


//--------------------------------------------------------------------
// Method addBlocks
//
// Input	: blockContent to add
//          : <blockNo blockNo blockNo ...> 
// Output   : none
// Purpose  : add blockNo to the tail 
//--------------------------------------------------------------------

	public void addBlocks (String blockNoContent)
	{
		StringTokenizer newBlockNo 
			= new StringTokenizer(blockNoContent, " ");
		int count = newBlockNo.countTokens();
		for ( int i = 0 ; i < count ; ++i ) 
			blockNo.addElement(new Integer(Integer.parseInt(newBlockNo.nextToken())));
		return;
	}


//--------------------------------------------------------------------
// Method deleteBlocks
//
// Input	: noOfBlocks to delete
// Output   : none
// Purpose  : delete blocks from tail 
//--------------------------------------------------------------------

	public void deleteBlocks (int noOfBlocks)
	{
		blockNo.setSize(blockNo.size() - noOfBlocks); 
		return;
	}


//--------------------------------------------------------------------
// Method typeCheck
//
// Input	: none
// Output   : flag true if it is that type
// Purpose  : check the type of fileAttribute
//--------------------------------------------------------------------

	public boolean isSystem()
	{
		return type.equals("s");
	}

	public boolean isDirectory()
	{
		return type.equals("d");
	}
	
	public boolean isText()
	{
		return type.equals("t");
	}

	public boolean isExecutable()
	{
		return type.equals("x");
	}

	public boolean isLink()
	{
		return type.equals("l");
	}

	public boolean isAvailable()
	{
		return type.equals("?");
	}
}

//--------------------------------------------------------------------
// End Class FileAttribute
//--------------------------------------------------------------------