<?php

class ListUtils
{
    public static function config_file_path($config_id)
    {
        return "/config/lcfg_$config_id.txt";
    }

    public static function read_config_file($config_id)
    {
        $path = ListUtils::config_file_path($config_id);

        $cfg = self::config_create();
        if (!is_file($path))
            return $cfg;

        $flags = FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES;
        $lines = file($path, $flags);
        if (!$lines)
            return $cfg;
        $order = false;
        foreach ($lines as $line)
        {
            $line = trim($line);
            if (strlen($line) == 0)
                continue;

            if ($order)
            {
                $cfg->order[] = $line;
                continue;
            }

            if (0 === strpos($line, '---'))
            {
                $order = true;
                continue;
            }

            $id = substr($line, 1);
            if ($line[0] == '+' || $line[0] == '-')
                $cfg->changes[$id] = $line[0];
        }
        return $cfg;
    }

    private static function config_create()
    {
        return (object) array('changes' => array(), 'order' => array());
    }

    ///////////////////////////////////////////////////////////////////////

    public static function read_on_off_file($path)
    {
        $on_off = self::on_off_create();
        if (!is_file($path))
            return $on_off;

        $flags = FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES;
        $lines = file($path, $flags);
        if (!$lines)
            return $on_off;
        foreach ($lines as $line)
        {
            $line = trim($line);
            if (strlen($line) == 0)
                continue;
            if (0 == strncmp($line, '---', 3))
                break;
            $id = substr($line, 1);
            if ($line[0] == '+' || $line[0] == '-')
                $on_off->changes[$id] = $line[0];
        }
        return $on_off;
    }

    public static function write_on_off_file($path, $on_off)
    {
        uksort($on_off->changes, 'strnatcasecmp');

        $str = '';
        foreach ($on_off->changes as $id => $sign)
            $str .= "$sign$id\n";

        return HD::write_to_file_using_tmp_if_changed($path, $str);
    }

    public static function get_enabled_idset_from_on_off(
        $all_list, $def_list, $on_off, $avoid_empty)
    {
        if (!isset($all_list))
            $all_list = $def_list;

        $all_idset = self::list_to_idset($all_list);
        $def_idset = self::list_to_idset($def_list);

        $idset = $def_idset;
        foreach ($on_off->changes as $id => $sign) {
            if ($sign == '-')
                unset($idset[$id]);
            else if (isset($all_idset[$id]))
                $idset[$id] = 1;
        }

        if (!$idset && $avoid_empty) {
            foreach ($def_idset as $k => $v) {
                $idset[$k] = $v;
                break;
            }
        }
        return $idset;
    }

    public static function update_on_off($on_off,
        $from_idset, $to_idset)
    {
        foreach ($from_idset as $id => $dummy) {
            if (!isset($to_idset[$id]))
                $on_off->changes[$id] = '-';
        }
        foreach ($to_idset as $id => $dummy) {
            if (!isset($from_idset[$id]))
                $on_off->changes[$id] = '+';
        }
    }

    private static function list_to_idset($list)
    {
        $idset = array();
        foreach ($list as $v)
        {
            $id = is_object($v) ? $v->id :
                (is_array($v) ? $v['id'] : (string) $v);
            $idset[$id] = 1;
        }
        return $idset;
    }

    private static function on_off_create()
    {
        return (object) array('changes' => array());
    }
}

?>
