<?php
///////////////////////////////////////////////////////////////////////////

require_once 'lib/hashed_array.php';
require_once 'lib/tv/abstract_tv.php';
require_once 'lib/tv/default_epg_item.php';

require_once 'flussonic_channel.php';

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

class FlussonicTv extends AbstractTv
{
    public function __construct()
    {
        parent::__construct(
            AbstractTv::MODE_CHANNELS_N_TO_M,
            FlussonicConfig::TV_FAVORITES_SUPPORTED,
            true);
    }

    public function get_fav_icon_url()
    {
        return FlussonicConfig::FAV_CHANNEL_GROUP_ICON_PATH;
    }

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

    protected function load_channels(&$plugin_cookies)
    {
        try
        {
            $doc = HD::http_get_document(FlussonicConfig::CHANNEL_LIST_URL);
        }
        catch (Exception $e)
        {
            throw new DuneException(
                'HTTP network error', 0,
                ActionFactory::show_error(
                    true,
                    'Ошибка связи',
                    array(
                        'Не удаётся подключиться к IPTV-серверу.',
                        'Проверьте подключение к сети Интернет.')));
        }
     
        $xml = simplexml_load_string($doc);

        if ($xml === false)
        {
            hd_print("Error: can not parse XML document.");
            hd_print("XML-text: $doc.");
            throw new Exception('Illegal XML document');
        }

        if ($xml->getName() !== 'tv_info')
        {
            hd_print("Error: unexpected node '" . $xml->getName() . "'. Expected: 'tv_info'");
            throw new Exception('Invalid XML document');
        }

        $this->channels = new HashedArray();
        $this->groups = new HashedArray();

        if ($this->is_favorites_supported())
        {
            $this->groups->put(
                new FavoritesGroup(
                    $this,
                    '__favorites',
                    FlussonicConfig::FAV_CHANNEL_GROUP_CAPTION,
                    FlussonicConfig::FAV_CHANNEL_GROUP_ICON_PATH));
        }

        $this->groups->put(
            new AllChannelsGroup(
                $this,
                FlussonicConfig::ALL_CHANNEL_GROUP_CAPTION,
                FlussonicConfig::ALL_CHANNEL_GROUP_ICON_PATH));

        foreach ($xml->tv_categories->children() as $xml_tv_category)
        {
            if ($xml_tv_category->getName() !== 'tv_category')
            {
                hd_print("Error: unexpected node '" . $xml_tv_category->getName() .
                    "'. Expected: 'tv_category'");
                throw new Exception('Invalid XML document');
            }

            $this->groups->put(
                new DefaultGroup(
                    strval($xml_tv_category->id),
                    strval($xml_tv_category->caption),
                    strval($xml_tv_category->icon_url)));
        }

        foreach ($xml->tv_channels->children() as $xml_tv_channel)
        {
            if ($xml_tv_channel->getName() !== 'tv_channel')
            {
                hd_print("Error: unexpected node '" . $xml_tv_channel->getName() .
                    "'. Expected: 'tv_channel'");
                throw new Exception('Invalid XML document');
            }

            $channel =
                new FlussonicChannel(
                    strval($xml_tv_channel->id),
                    strval($xml_tv_channel->caption),
                    strval($xml_tv_channel->icon_url),
                    strval($xml_tv_channel->streaming_url),
                    intval($xml_tv_channel->number),
                    intval($xml_tv_channel->num_past_epg_days),
                    intval($xml_tv_channel->num_future_epg_days));

            $this->channels->put($channel);

            foreach ($xml_tv_channel->tv_categories->children() as $xml_tv_cat_id)
            {
                if ($xml_tv_cat_id->getName() !== 'tv_category_id')
                {
                    hd_print("Error: unexpected node '" . $xml_tv_cat_id->getName() .
                        "'. Expected: 'tv_category_id'");
                    throw new Exception('Invalid XML document');
                }

                $tv_category_id = intval($xml_tv_cat_id);

                $group = $this->groups->get($tv_category_id);

                // Link group and channel.

                $channel->add_group($group);
                $group->add_channel($channel);
            }
        }

        if (FlussonicConfig::CHANNEL_SORT_FUNC_CB != null)
            $this->channels->usort(FlussonicConfig::CHANNEL_SORT_FUNC_CB);
    }

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

    public function get_day_epg_iterator($channel_id, $day_start_ts, &$plugin_cookies)
    {
        if (FlussonicConfig::EPG_URL_FORMAT == null)
            return array();

        try
        {
            $doc =
                HD::http_get_document(
                    sprintf(
                        FlussonicConfig::EPG_URL_FORMAT,
                        $channel_id,
                        $day_start_ts));
        }
        catch (Exception $e)
        {
            throw new DuneException(
                'HTTP network error', 0,
                ActionFactory::show_error(
                    true,
                    'Ошибка связи',
                    array(
                        'Не удаётся подключиться к IPTV-серверу.',
                        'Проверьте подключение к сети Интернет.')));
        }
     
        $xml = simplexml_load_string($doc);

        if ($xml === false)
        {
            hd_print("Error: can not parse XML document.");
            hd_print( "XML-text: $doc.");
            throw new Exception('Illegal XML document');
        }

        if ($xml->getName() !== 'epg')
        {
            hd_print("Error: unexpected node '" . $xml->getName() . "'. Expected: 'NewDataSet'");
            throw new Exception('Invalid XML document');
        }

        $epg = array();

        foreach ($xml->children() as $epg_item)
        {
            if ($epg_item->getName() !== 'epg_item')
            {
                hd_print("Error: unexpected node '" . $epg_item->getName() .
                    "'. Expected: 'epg_item'");
                throw new Exception('Invalid XML document');
            }

            $epg[] =
                new DefaultEpgItem(
                    strval($epg_item->caption),
                    strval($epg_item->description),
                    intval($epg_item->start_time),
                    intval($epg_item->stop_time));
        }

        return
            new EpgIterator(
                $epg,
                $day_start_ts,
                $day_start_ts + 86400);
    }
}

///////////////////////////////////////////////////////////////////////////
?>
