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

import com.jniwrapper.Bool;
import com.jniwrapper.Function;
import com.jniwrapper.NoSuchFunctionException;
import com.jniwrapper.Pointer;
import com.jniwrapper.win32.LastErrorException;

/**
 * Class allows to obtain information about the current state of both physical and virtual memory,
 * including extended memory.<br>
 * Function uses <code>GlobalMemoryStatusEx</code> API funciton and {@link MemoryStatusEx} structure
 * for getting information starting from Windows2000 and higher versions.<br>
 * The <code>GlobalMemoryStatus</code> API funciton and {@link MemoryStatus} structure are being used on earlier versions
 * of operating systems.
 *
 * @author Vadim Ridosh
 */
public class MemoryInfo
{
    private long memoryLoad;
    private long totalPhys;
    private long availPhys;
    private long totalPageFile;
    private long availPageFile;
    private long totalVirtual;
    private long availVirtual;
    private long availExtendedVirtual;

    /**
     * Creates new instance of MemoryInfo class.
     */
    public MemoryInfo()
    {
        try
        {
            Bool result = new Bool();
            Function globalMemoryStatusEx = Kernel32.getInstance().getFunction("GlobalMemoryStatusEx");
            MemoryStatusEx memoryStatusEx = new MemoryStatusEx();
            long errorCode = globalMemoryStatusEx.invoke(result, new Pointer(memoryStatusEx));
            if (!result.getValue())
            {
                throw new LastErrorException(errorCode);
            }
            memoryLoad = memoryStatusEx.getMemoryLoad();
            totalPhys = memoryStatusEx.getTotalPhys();
            availPhys = memoryStatusEx.getAvailPhys();
            totalPageFile = memoryStatusEx.getTotalPageFile();
            availPageFile = memoryStatusEx.getAvailPageFile();
            totalVirtual = memoryStatusEx.getTotalVirtual();
            availVirtual = memoryStatusEx.getAvailVirtual();
            availExtendedVirtual = memoryStatusEx.getAvailExtendedVirtual();
        }
        catch (NoSuchFunctionException e)
        {
            MemoryStatus memoryStatus = new MemoryStatus();
            memoryLoad = memoryStatus.getMemoryLoad();
            totalPhys = memoryStatus.getTotalPhys();
            availPhys = memoryStatus.getAvailPhys();
            totalPageFile = memoryStatus.getTotalPageFile();
            availPageFile = memoryStatus.getAvailPageFile();
            totalVirtual = memoryStatus.getTotalVirtual();
            availVirtual = memoryStatus.getAvailVirtual();
            availExtendedVirtual = 0; 
        }
    }

    /**
     * Number between 0 and 100 that specifies the approximate percentage of physical memory
     * that is in use (0 indicates no memory use and 100 indicates full memory use).
     *
     * @return approximate percentage of physical memory that is in use
     */
    public long getMemoryLoad()
    {
        return memoryLoad;
    }

    /**
     * Total size of physical memory, in bytes.
     *
     * @return total size of physical memory
     */
    public long getTotalPhys()
    {
        return totalPhys;
    }

    /**
     * Size of physical memory available, in bytes.
     *
     * @return size of physical memory available
     */
    public long getAvailPhys()
    {
        return availPhys;
    }

    /**
     * Size of the committed memory limit, in bytes.
     *
     * @return size of the committed memory limit
     */
    public long getTotalPageFile()
    {
        return totalPageFile;
    }

    /**
     * Size of available memory to commit, in bytes.
     *
     * @return size of available memory to commit
     */
    public long getAvailPageFile()
    {
        return availPageFile;
    }

    /**
     * Total size of the user mode portion of the virtual address space of the calling process, in bytes
     *
     * @return total size of the user mode portion of the virtual address space
     */
    public long getTotalVirtual()
    {
        return totalVirtual;
    }

    /**
     * Size of unreserved and uncommitted memory in the user mode portion of the virtual
     * address space of the calling process, in bytes.
     *
     * @return size of unreserved and uncommitted memory in the user mode portion of the virtual address space
     */
    public long getAvailVirtual()
    {
        return availVirtual;
    }

    /**
     * Size of unreserved and uncommitted memory in the extended portion of the virtual
     * address space of the calling process, in bytes
     *
     * @return size of unreserved and uncommitted memory in the extended mode portion of the virtual address space
     */
    public long getAvailExtendedVirtual()
    {
        return availExtendedVirtual;
    }
}