<?php
/*
   The Index software may be freely distributed.
   See license.txt for details.
*/

define('CATEGORIES', ROOT . 'list/categories.idx');
define('INDEX', ROOT . 'list/nethack.idx');
define('VISITORINDEX', ROOT . 'list/visitor.idx');
define('DELETEDINDEX', ROOT . 'list/deleted.idx');

function pos_sort($value_a, $value_b)
{
    return ($value_a['position'] - $value_b['position']);
}
function date_sort($value_a, $value_b)
{
    return (($ret = $value_b['date'] - $value_a['date']) 
            ? $ret 
            : pos_sort($value_a, $value_b));
}
function url_sort($value_a, $value_b)
{
    return (($ret = strcmp($value_a['url'], $value_b['url'])) 
            ? $ret 
            : pos_sort($value_a, $value_b));
}
function auth_sort($value_a, $value_b)
{
    return (($ret = strcmp($value_a['author'], $value_b['author'])) 
            ? $ret 
            : pos_sort($value_a, $value_b));
}
function cat_sort($value_a, $value_b)
{
    $ca  =explode(",", $value_a['category']);
    $cb  =explode(",", $value_b['category']);
    return (($ret = strcmp($ca[0], $cb[0])) 
            ? $ret 
            : popu_sort($value_a, $value_b));
}
function catpos_sort($value_a, $value_b)
{
    $ca  =explode(",", $value_a['category']);
    $cb  =explode(",", $value_b['category']);
    return (($ret = strcmp($ca[0], $cb[0])) 
            ? $ret 
            : pos_sort($value_a, $value_b));
}
function name_sort($value_a, $value_b)
{
    return (($ret = strcmp($value_a['name'], $value_b['name'])) 
            ? $ret 
            : pos_sort($value_a, $value_b));
}
function popu_sort($value_a, $value_b)
{
    global $counts;
    global $combilist;

    $key_a = $value_a['key'];
    $key_b = $value_b['key'];
    return (($ret = $counts[$key_b] - $counts[$key_a])
            ? $ret 
            : pos_sort($combilist[$key_a], $combilist[$key_b]));
}


function filter($value, $field, $needle)
{
    if ($needle == "")
        return true;
    return eregi($needle, $value[$field]);
}


function ReadCategoryList()
{
    global $categories;
    global $introduction;
    require(CATEGORIES);
}


function ReadList()
{
    global $list;
    global $visitorlist;
    global $deletedlist;
    global $combilist;
    ReadCategoryList();
    // Make sure counts are only written if read correctly
    global $listread;
    $listread = 0;
    // The included file will set listread to true, iff it gets read
    // completely.
    require(INDEX);

    ReadVisitorList();
    if (is_array($visitorlist))
        $combilist = $list + $visitorlist;
    else
        $combilist = $list;

    ReadDeletedList();
}

function SortList(&$list, $field)
{
    ReadCounts();
    if ($field == "url")
        uasort($list, 'url_sort');
    elseif ($field == "date")
        uasort($list, 'date_sort');
    elseif ($field == "author")
        uasort($list, 'auth_sort');
    elseif ($field == "catpos")
        uasort($list, 'catpos_sort');
    elseif ($field == "category")
        uasort($list, 'cat_sort');
    elseif ($field == "name")
        uasort($list, 'name_sort');
    elseif ($field == "count")
    {
        uasort($list, 'popu_sort');
    }
}

function FilterList($field, $conts)
{
    global $combilist;
    global $exclude;

    reset($combilist);    
    while (list($key, $value) = each($combilist))
    {
        if ($field == 'key')
        {
            if ($key != $conts)
                $exclude[$key] = true;
        }
        elseif ($field == '') // any
        {
            if (
                    !filter($value, 'name', $conts)
                and !filter($value, 'author', $conts)
                and !filter($value, 'url', $conts)
                and !filter($value, 'category', $conts)
                and !filter($value, 'desc', $conts)
                and !NoteExistsContaining($key, $conts)
               )
                $exclude[$key] = true;
        }
        elseif ($field == 'notes')
        {
            if (!NoteExistsContaining($key, $conts))
                $exclude[$key] = true;
                
        }
        else 
        {
            if (!filter($value, $field, $conts))
                $exclude[$key] = true;
        }
    }
}

function Excluded($key)
{
    global $exclude;
    return $exclude[$key];
}


function ReadVisitorList()
{
    global $visitorlist;
    // Make sure counts are only written if read correctly
    global $visitorlistread;
    $visitorlistread = 0;
    // The included file will set visitorlistread to true, iff it gets read
    // completely.
    if (file_exists(VISITORINDEX))
        include(VISITORINDEX);
    else
    {
        // Make sure we can write the first time
        $visitorlistread = 1;
    }
}

function ReadDeletedList()
{
    global $deletedlist;
    // Make sure counts are only written if read correctly
    global $deletedlistread;
    $deletedlistread = 0;
    // The included file will set deletedlistread to true, iff it gets read
    // completely.
    if (file_exists(DELETEDINDEX))
        include(DELETEDINDEX);
    else
    {
        // Make sure we can write the first time
        $deletedlistread = 1;
    }
}


function MakeItem($name, $author, $url, $desc, $category, $email)
{
    $desc = addlocallinks(text2html($desc));
    $email = text2html($email);

    $item = 
        array('name'=> "$name",
              'author' => "$author",
              'url' => $url,
              'desc' => $desc,
              'category' => "$category",
              'email' => $email,
              'date' => time()
             );
    return $item;
}


function MakeVisitorItem($name, $author, $url, $desc, $category, $email)
{
    return MakeItem($name, $author, $url, $desc, "80visitor,$category", $email);
}


function StoreVisitorItem($visitoritem)
{
    StoreItem("", $visitoritem, "visitorlist", VISITORINDEX, 9999);
}


function StoreDeletedItem($key, $deleteditem)
{
    $deleteditem['date'] = time();
    StoreItem($key, $deleteditem, "deletedlist", DELETEDINDEX, 9999);
}


function RemoveVisitorItem($visitorkey, $keepasdeleted)
{
    global $visitorlist;
    RemoveItem($visitorkey, "visitorlist", VISITORINDEX, $keepasdeleted);
}

function StoreItem($key, $item, $listname, $filename, $position)
{
    global $deletedlist, $visitorlist, $list;
    // Make a key
    if ($key == "")
    {
        $key = ereg_replace("[^A-Za-z0-9]+", "", $item['name']);
        $newkey = $key;
        $x = "";
        while (($deletedlist[$newkey]['name'] != "")
                or ($visitorlist[$newkey]['name'] != "")
                or ($list[$newkey]['name'] != ""))
        {
            $x++;
            $newkey = "$key$x";
        }
        $key = $newkey;
    }

    // Add new item
    $item['position'] = $position;
    ${$listname}[$key] = $item;

    // Write the list
    WriteList($listname, $filename);
}


function RemoveItem($key, $listname, $filename, $keepasdeleted)
{
    // Store for posterity
    if ($keepasdeleted)
    {
        // Make sure that we can delete non-existent items: Don't try
        // to remember these.
        if (isset($GLOBALS[$listname][$key]))
            StoreDeletedItem($key, $GLOBALS[$listname][$key]);
    }
    // Manual page for unset says this is the only proper way
    unset($GLOBALS[$listname][$key]);
    WriteList($listname, $filename);
}


function WriteList($listname, $filename)    
{
    global $$listname;

    $listreadname = $listname . "read";
    global $$listreadname;
    if ($$listreadname)
    {
        SortList($$listname, 'catpos');
        $f = fopen($filename, "w");
        fwrite($f, "<?php\n");
        fwrite($f, "\$$listname = array (\n"); // array
        reset($$listname);
        $count = 0;
        while (list($key, $value) = each($$listname))
        {
            // We must not write unset items, but sorting creates an empty
            // value for unset keys. However, name can never be empty...
            if ($value['name'] == '')
                continue;

            if ($count != 0)
                fwrite($f, ",\n\n");

            fwrite($f, "'$key' => array (\n");
            // Write record
            fwrite($f, "    'key' => '");
            fwrite($f, $key);
            fwrite($f, "',\n");
            fwrite($f, "    'position' => ");
            fwrite($f, $count);
            fwrite($f, ",\n");
            fwrite($f, "    'name' => '");
            fwrite($f, escapequotes($value['name']));
            fwrite($f, "',\n");
            fwrite($f, "    'author' => '");
            fwrite($f, escapequotes($value['author']));
            fwrite($f, "',\n");
            fwrite($f, "    'url' => '");
            fwrite($f, escapequotes($value['url']));
            fwrite($f, "',\n");
            fwrite($f, "    'desc' => '");
            fwrite($f, escapequotes($value['desc']));
            fwrite($f, "',\n");
            fwrite($f, "    'category' => '");
            fwrite($f, $value['category']);
            fwrite($f, "',\n");
            fwrite($f, "    'date' => '");
            fwrite($f, $value['date']);
            fwrite($f, "',\n");
            fwrite($f, "    'email' => '");
            fwrite($f, escapequotes($value['email']));
            fwrite($f, "'\n)");

            $count++;
        }
        fwrite($f, "\n);\n\n"); // array
        
        fwrite($f, "// If we read all the way, this variable is set.\n");
        fwrite($f, "// If something goes wrong, this variable is not set\n");
        fwrite($f, "// and we will never write.\n");
        fwrite($f, "\$$listreadname = 1;\n");

        fwrite($f, "?>\n");
        fclose($f);
    }
}


?>