#if defined _file_vault_included
#endinput
#endif

#define _file_vault_included

/**
* FVault was created by Exolent on 8/24/08
* This vault system uses actual files and no modules
* It is very flexible and has many features
* Visit this page for more information: http://forums.alliedmods.net/showthread.php?t=76453
*/

#include <amxmodx>

#define _vault_dir "addons/amxmodx/data/file_vault"

/**
* Retrieves a key name specified by its number
*
* @param vaultname Vault name to look in
* @param keynum Key number within the vault to find key name
* @param key String which key name will be copied to
* @param len Length of key name
* @return Returns 1 on success, 0 on failue.
*/
stock fvault_get_keyname(const vaultname[], const keynum, key[], len)
{
new filename[128];
_FormatVaultName(vaultname, filename, sizeof(filename) - 1);

new vault = fopen(filename, "rt");

new _data[64], _other[3];

new line = -1;

while( !feof(vault) )
{
fgets(vault, _data, sizeof(_data) - 1);

if( ++line == keynum )
{
parse(_data, key, len, _other, sizeof(_other) - 1);

fclose(vault);

return 1;
}
}

fclose(vault);

return 0;
}

/**
* Retrieves a key number specified by its name
*
* @param vaultname Vault name to look in
* @param key Key name to search for
* @return Returns key number on success, -1 on failure
*/
stock fvault_get_keynum(const vaultname[], const key[])
{
new filename[128];
_FormatVaultName(vaultname, filename, sizeof(filename) - 1);

new vault = fopen(filename, "rt");

new _data[70], _key[64], _other[3];

new line = -1;

while( !feof(vault) )
{
fgets(vault, _data, sizeof(_data) - 1);
parse(_data, _key, sizeof(_key) - 1, _other, sizeof(_other) - 1);

line++;

if( equal(_key, key) )
{
fclose(vault);

return line;
}
}

fclose(vault);

return -1;
}

/**
* Retrieves data specified by a key
*
* @param vaultname Vault name to look in
* @param key Key name to look for the data
* @param data String which data will be copied to
* @param len Length of data
* @return Returns 1 on success, 0 on failue.
*/
stock fvault_get_data(const vaultname[], const key[], data[], len)
{
new filename[128];
_FormatVaultName(vaultname, filename, sizeof(filename) - 1);

new vault = fopen(filename, "rt");

new _data[512], _key[64];

while( !feof(vault) )
{
fgets(vault, _data, sizeof(_data) - 1);
parse(_data, _key, sizeof(_key) - 1, data, len);

if( equal(_key, key) )
{
fclose(vault);

return 1;
}
}

fclose(vault);

copy(data, len, "");

return 0;
}

/**
* Sets data of a key
*
* @param vaultname Vault name to look in
* @param key Key name to which data will be set
* @param data Data to set to key
* @return Does not return a value.
*/
stock fvault_set_data(const vaultname[], const key[], const data[])
{
static const temp_vault_name[] = "fvault_set_data.txt";

new file = fopen(temp_vault_name, "wt");

new filename[128];
_FormatVaultName(vaultname, filename, sizeof(filename) - 1);

new vault = fopen(filename, "rt");

new _data[512], _key[64], _other[3];

new bool:replaced = false;

while( !feof(vault) )
{
fgets(vault, _data, sizeof(_data) - 1);
parse(_data, _key, sizeof(_key) - 1, _other, sizeof(_other) - 1);

if( equal(_key, key) && !replaced )
{
fprintf(file, "^"%s^" ^"%s^"^n", key, data);

replaced = true;
}
else
{
fputs(file, _data);
}
}

if( !replaced )
{
fprintf(file, "^"%s^" ^"%s^"^n", key, data);
}

fclose(file);
fclose(vault);

delete_file(filename);

while( !rename_file(temp_vault_name, filename, 1) ) { }

//delete_file(temp_vault_name);
}

/**
* Retrieves total keys located within the vault
*
* @param vaultname Vault name to look in
* @return Returns amount of keys in vault
*/
stock fvault_size(const vaultname[])
{
new filename[128];
_FormatVaultName(vaultname, filename, sizeof(filename) - 1);

return file_size(filename, 1) - 1;
}

/**
* Retrieves a vault name specified by its number
*
* @param vaultnum Vault number to find the vault name
* @param vaultname String which vault name will be copied to
* @param len Length of vault name
* @return Returns 1 on success, 0 on failue.
*/
stock fvault_get_vaultname(const vaultnum, vaultname[], len)
{
new filenum;

new dir = open_dir(_vault_dir, vaultname, len);

do
{
if( equal(vaultname, ".") || equal(vaultname, "..") )
{
continue;
}

if( filenum == vaultnum )
{
close_dir(dir);

replace(vaultname, len, ".txt", "");

return 1;
}

++filenum;
}
while( next_file(dir, vaultname, len) );

close_dir(dir);

copy(vaultname, len, "");

return 0;
}

/**
* Retrieves a vault number specified by its name
*
* @param vaultname Vault name to find the number
* @return Returns vault number on success, -1 on failure
*/
stock fvault_get_vaultnum(const vaultname[])
{
new filename[128], filenum;

new dir = open_dir(_vault_dir, filename, sizeof(filename) - 1);

do
{
if( equal(filename, ".") || equal(filename, "..") )
{
continue;
}

replace(filename, sizeof(filename) - 1, ".txt", "");

if( equal(filename, vaultname) )
{
close_dir(dir);

return filenum;
}

++filenum;
}
while( next_file(dir, filename, sizeof(filename) - 1) );

close_dir(dir);

copy(vaultname, len, "");

return -1;
}

/**
* Retrieves total vaults ever created
*
* @return Returns amount of vaults
*/
stock fvault_total()
{
new vaultname[128], filename[128];
new dir = open_dir(_vault_dir, vaultname, sizeof(vaultname) - 1);

new filenum;
do
{
if( equal(vaultname, ".") || equal(vaultname, "..") )
{
continue;
}

formatex(filename, sizeof(filename) - 1, "%s/%s", _vault_dir, vaultname);
if( file_exists(filename) )
{
++filenum;
}
}
while( next_file(dir, vaultname, sizeof(vaultname) - 1) );

close_dir(dir);

return filenum;
}

/**
* Removes a key from a vault
*
* @param vaultname Vault name to look in
* @param key Key to remove
* @return No return
*/
stock fvault_remove_key(const vaultname[], const key[])
{
static const temp_vault_name[] = "fvault_remove_key.txt";

new file = fopen(temp_vault_name, "wt");

new filename[128];
_FormatVaultName(vaultname, filename, sizeof(filename) - 1);

new vault = fopen(filename, "rt");

new _data[512], _key[64], _other[3];

while( !feof(vault) )
{
fgets(vault, _data, sizeof(_data) - 1);
parse(_data, _key, sizeof(_key) - 1, _other, sizeof(_other) - 1);

if( !equal(_key, key) )
{
fputs(file, _data);
}
}

fclose(file);
fclose(vault);

delete_file(filename);

while( !rename_file(temp_vault_name, filename, 1) ) { }

delete_file(temp_vault_name);
}

/**
* Clears all key entries for a vault
*
* @param vaultname Vault name to erase
* @return No return
*/
stock fvault_clear(const vaultname[])
{
new filename[128];
_FormatVaultName(vaultname, filename, sizeof(filename) - 1);

delete_file(filename);

fclose(fopen(filename, "wt"));
}

stock _FormatVaultName(const vaultname[], filename[], len)
{
static const invalid_chars[][] =
{
"/", "\", "*", ":", "?", "^"", "<", ">", "|"
};

static tempvault[128], i;
copy(tempvault, sizeof(tempvault) - 1, vaultname);

for( i = 0; i < sizeof(invalid_chars); i++ )
{
replace(tempvault, sizeof(tempvault) - 1, invalid_chars[i], "");
}

if( !dir_exists(_vault_dir) )
{
mkdir(_vault_dir);
}

formatex(filename, len, "%s/%s.txt", _vault_dir, tempvault);
}
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1033\\ f0\\ fs16 \n\\ par }
*/

