/*
 * Copyright (c) 2000-2009 TeamDev Ltd. All rights reserved.
 * TeamDev PROPRIETARY and CONFIDENTIAL.
 * Use is subject to license terms.
 */
package com.jniwrapper.win32.io;

import com.jniwrapper.util.Logger;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.List;

/**
 * The FolderInfo class is a container of folder information.
 * 
 * @author Serge Piletsky
 */
public class FolderInfo extends FileInfo
{
    private static final Logger LOG = Logger.getInstance(FolderInfo.class);
    
    private List _files = new ArrayList();
    private boolean _recursive = true;
    private int _fileCount = 0;
    private FileFilter _fileFilter = null;

    /**
     * Creates instance of the <code>FolderInfo</code>
     *
     * @param fileName Path to the folder
     */
    public FolderInfo(String fileName)
    {
        super(fileName);
    }

    /**
     * Creates instance of the <code>FolderInfo</code> with specified file filter
     *
     * @param path Path to the folder
     * @param filter File filter
     * @param recursive If this value is TRUE subfolders and theirs files will be listed
     * @throws IllegalArgumentException
     */
    public FolderInfo(String path, FileFilter filter, boolean recursive) throws IllegalArgumentException
    {
        super(path, FileSystem.getFileAttributes(path).getFlags(), new File(path).length(), new File(path).lastModified());
        _fileFilter = filter;
        _recursive = recursive;
    }

    /**
     * Creates instance of the <code>FolderInfo</code>
     *
     * @param path Path to the folder
     * @param recursive If this value is TRUE subfolders and theirs files will be listed
     */
    public FolderInfo(String path, boolean recursive)
    {
        this(path, null, recursive);
    }

    /**
     * Loads the contents of the specified folder
     */
    protected void loadFiles(FolderInfo result, File rootFolder)
    {
        File[] files = _fileFilter == null ? rootFolder.listFiles() : rootFolder.listFiles(_fileFilter);
        while (files == null)
        {
            try
            {
                Thread.sleep(10);
            }
            catch (InterruptedException e)
            {
                LOG.error("", e);
            }
            files = _fileFilter == null ? rootFolder.listFiles() : rootFolder.listFiles(_fileFilter);
        }
        for (int i = 0; i < files.length; i++)
        {
            File file = files[i];
            _fileCount++;
            String fileName = file.getAbsolutePath();
            if (_recursive && file.isDirectory())
            {
                FolderInfo subfolder = new FolderInfo(fileName, _recursive);
                loadFiles(subfolder, file);
                result._files.add(subfolder);
                _fileCount += subfolder.getFileCount();
            }
            else
            {
                result._files.add(new FileInfo(fileName,
                        FileSystem.getFileAttributes(fileName).getFlags(),
                        file.length(),
                        file.lastModified()));
            }
        }
    }

    /**
     * Loads the contents of this folder
     */
    public void load()
    {
        _files.clear();
        loadFiles(this, new File(getFileName()));
    }

    /**
     * Returns the count of the files in this folder
     * @return The count of the files in this folder
     */
    public int getFileCount()
    {
        return _fileCount;
    }

    /**
     * Returns content of this folder
     *
     * @return Content of this folder
     */
    public List getFiles()
    {
        return _files;
    }
}