function twitch_status_channels_edit()
{
    ?>
	<script type="text/javascript">
		function twitchStatus_AddChannelRow()
		{
			jQuery('#twitchStatusChannels tbody').append(jQuery('#twitchStatusChannels tbody tr:last()').clone());
			jQuery('#twitchStatusChannels tbody tr:last() button').show();
		}

		function twitchStatus_RemoveChannelRow(button)
		{
			jQuery(button).closest('tr').remove();
		}

	</script>

	<?php 
    $channels = twitch_status_get_channels();
    if (empty($channels)) {
        $channels[] = array('name' => '', 'selectors' => '');
    }
    echo '<table id="twitchStatusChannels">';
    echo '<thead>';
    echo '<tr>';
    echo '<th style="width: 30px"></th>';
    echo '<th>' . __('Channel name', 'twitch-status') . '<p class="description">' . __("Your Twitch channel name", 'twitch-status') . '</p></th>';
    echo '<th style="width: 500px">' . __('jQuery selectors', 'twitch-status') . '<p class="description">' . __("<a href=\"http://api.jquery.com/category/selectors/\" target=\"_blank\">jQuery selectors</a> matching the places you want to insert the stream status tags.<br />Enter one selector per line. You can add as much selectors as you want.", 'twitch-status') . '</p></th>';
    echo '</tr>';
    echo '</thead>';
    echo '<tbody>';
    $first = true;
    foreach ($channels as $channel) {
        echo '<tr>';
        echo '<td style="width: 30px"><button class="button button-primary" type="button" style="' . ($first ? 'display: none' : '') . '" onclick="twitchStatus_RemoveChannelRow(this)">X</button></td>';
        echo '<td><input name="twitch_status_channels[names][]" size="40" type="text" value="' . esc_attr($channel['name']) . '" /></td>';
        echo '<td><textarea class="large-text code" name="twitch_status_channels[selectors][]" cols="40" rows="3">' . htmlspecialchars(implode("\n", $channel['selectors'])) . '</textarea></td>';
        echo '</tr>';
        $first = false;
    }
    echo '</tbody>';
    echo '<tfoot>';
    echo '<tr><td colspan="3"><button class="button button-primary" type="button" onclick="twitchStatus_AddChannelRow()">' . __('Add channel', 'twitch-status') . '</button></td></tr>';
    echo '</tfoot>';
    echo '</table>';
}
    /**
     * Widget admin form
     * @param array $instance
     */
    public function form($instance)
    {
        if (!isset($instance['title'])) {
            $instance['title'] = __('Twitch', 'twitch-status');
        }
        if (!isset($instance['target'])) {
            $instance['target'] = 'channel';
        }
        // Use the first available channel for backward compatibility with v1.1
        if (empty($instance['channel'])) {
            $instance['channel'] = reset(array_keys(twitch_status_get_channels()));
        }
        ?>
			<p>
				<label for="<?php 
        echo $this->get_field_id('title');
        ?>
"><?php 
        _e('Title:');
        ?>
</label>
				<input class="widefat" id="<?php 
        echo $this->get_field_id('title');
        ?>
" name="<?php 
        echo $this->get_field_name('title');
        ?>
" type="text" value="<?php 
        echo esc_attr($instance['title']);
        ?>
" />

				<label for="<?php 
        echo $this->get_field_id('channel');
        ?>
"><?php 
        _e('Channel:', 'twitch-status');
        ?>
</label>
				<select class="widefat" id="<?php 
        echo $this->get_field_id('channel');
        ?>
" name="<?php 
        echo $this->get_field_name('channel');
        ?>
">
					<?php 
        foreach (twitch_status_get_channels() as $channel) {
            echo '<option value="' . esc_attr($channel['name']) . '"' . ($channel['name'] == $instance['channel'] ? ' selected' : '') . '>' . esc_attr($channel['name']) . '</option>';
        }
        ?>
				</select>

				<label><?php 
        echo __("\"Play\" button target", 'twitch-status');
        ?>
</label><br/>
				<input type="radio" name="<?php 
        echo $this->get_field_name('target');
        ?>
" id="<?php 
        echo $this->get_field_id('target_url');
        ?>
" value="url"<?php 
        echo @$instance['target'] == 'url' ? ' checked="checked"' : '';
        ?>
>
				<label for="<?php 
        echo $this->get_field_id('target_url');
        ?>
"><?php 
        echo __('URL:', 'twitch-status');
        ?>
</label>
				<input type="text" name="<?php 
        echo $this->get_field_name('url');
        ?>
" value="<?php 
        echo esc_attr(@$instance['url']);
        ?>
"><br />

				<input type="radio" name="<?php 
        echo $this->get_field_name('target');
        ?>
" id="<?php 
        echo $this->get_field_id('target_channel');
        ?>
" value="channel"<?php 
        echo @$instance['target'] == 'channel' ? ' checked="checked"' : '';
        ?>
>
				<label for="<?php 
        echo $this->get_field_id('target_channel');
        ?>
"><?php 
        echo __('Your Twitch.tv channel', 'twitch-status');
        ?>
</label><br />

				<input type="radio" name="<?php 
        echo $this->get_field_name('target');
        ?>
" id="<?php 
        echo $this->get_field_id('target_page');
        ?>
" value="page"<?php 
        echo @$instance['target'] == 'page' ? ' checked="checked"' : '';
        ?>
>
				<label for="<?php 
        echo $this->get_field_id('target_page');
        ?>
"><?php 
        echo __('Blog page:', 'twitch-status');
        ?>
</label>

				<select name="<?php 
        echo $this->get_field_name('page');
        ?>
" id="<?php 
        echo $this->get_field_id('page');
        ?>
">

				<?php 
        foreach (get_pages() as $aPage) {
            echo '<option value="' . $aPage->ID . '"' . (@$instance['page'] == $aPage->ID ? ' selected' : '') . '>' . htmlspecialchars($aPage->post_title) . '</option>';
        }
        ?>

				</select><br />

				<input type="checkbox" name="<?php 
        echo $this->get_field_name('newtab');
        ?>
" id="<?php 
        echo $this->get_field_id('newtab');
        ?>
" value="newtab"<?php 
        echo @$instance['newtab'] ? ' checked="checked"' : '';
        ?>
>
				<label for="<?php 
        echo $this->get_field_id('newtab');
        ?>
"><?php 
        echo __('Open in a new tab', 'twitch-status');
        ?>
</label>
			</p>
		<?php 
    }
/**
 * Retrieve channel and stream data from Twitch.tv
 * Called by AJAXaction
 * @return void
 */
function twitch_status_get_channel_status_ajax()
{
    header('Content-type: application/json; charset=utf-8');
    // Fetch stream and channel information from Twitch
    $now = time();
    $jsonData = array();
    foreach (twitch_status_get_channels() as $channelName => $channel) {
        $channelName = preg_replace('/[^0-9a-zA-Z_-]/', '', $channelName);
        $channelFilename = TWITCH_STATUS_BASE . 'cache/' . $channelName . '-channel.json';
        $streamFilename = TWITCH_STATUS_BASE . 'cache/' . $channelName . '-stream.json';
        // Update channel information from cache
        if ($now - @filemtime($channelFilename) >= 15) {
            $rawChannelData = @file_get_contents('https://api.twitch.tv/kraken/channels/' . $channelName);
            if (!empty($rawChannelData)) {
                file_put_contents($channelFilename, $rawChannelData);
            } else {
                $rawChannelData = @file_get_contents($channelFilename);
            }
        } else {
            $rawChannelData = @file_get_contents($channelFilename);
        }
        // Update stream status information from cache
        if ($now - @filemtime($streamFilename) >= 15) {
            $rawStreamData = @file_get_contents('https://api.twitch.tv/kraken/streams/' . $channelName);
            if (!empty($rawStreamData)) {
                file_put_contents($streamFilename, $rawStreamData);
            } else {
                $rawStreamData = @file_get_contents($streamFilename);
            }
        } else {
            $rawStreamData = @file_get_contents($streamFilename);
        }
        $data = array();
        $channelData = @json_decode($rawChannelData, true);
        $streamData = @json_decode($rawStreamData, true);
        if (!empty($channelData) && !empty($streamData)) {
            if (!empty($channelData['error']) || !empty($streamData['error'])) {
                $data['status'] = 'error';
            } else {
                $data['status'] = empty($streamData['stream']) ? 'offline' : 'online';
                $data['statusTxt'] = empty($streamData['stream']) ? __('Offline', 'twitch-status') : __('Online', 'twitch-status');
                $data['channel'] = $channelData;
                $data['stream'] = $streamData['stream'];
                $data['playingHTML'] = sprintf(__("%s playing %s", 'twitch-status'), '<a href="http://www.twitch.tv/' . urlencode($channelData['name']) . '/profile" target="_blank">' . htmlspecialchars($channelData['display_name']) . '</a>', '<a href="http://www.twitch.tv/directory/game/' . str_replace('+', ' ', urlencode($channelData['game'])) . '" target="_blank">' . htmlspecialchars($channelData['game']) . '</a>');
            }
        } else {
            $data['status'] = 'error';
        }
        $jsonData[] = $data;
    }
    echo json_encode($jsonData);
    die;
}