int CSelectChannelWidget::InitZapitChannelHelper(CZapitClient::channelsMode mode)
{
	std::vector<CMenuWidget *> toDelete;
	CMenuWidget mctv(LOCALE_TIMERLIST_BOUQUETSELECT, NEUTRINO_ICON_SETTINGS, width);
	mctv.addIntroItems();

	for (int i = 0; i < (int) g_bouquetManager->Bouquets.size(); i++) {
		CMenuWidget* mwtv = new CMenuWidget(LOCALE_TIMERLIST_CHANNELSELECT, NEUTRINO_ICON_SETTINGS, width);
		toDelete.push_back(mwtv);
		mwtv->addIntroItems();
		ZapitChannelList channels;
		if (mode == CZapitClient::MODE_RADIO)
			g_bouquetManager->Bouquets[i]->getRadioChannels(channels);
		else
			g_bouquetManager->Bouquets[i]->getTvChannels(channels);
		for(int j = 0; j < (int) channels.size(); j++) {
			CZapitChannel * channel = channels[j];
			char cChannelId[60] = {0};
			snprintf(cChannelId, sizeof(cChannelId), "ZC%c:%d|%" PRIx64 "#", (mode==CZapitClient::MODE_TV)?'T':'R', channel->number, channel->channel_id);

			CMenuForwarder * chan_item = new CMenuForwarder(channel->getName(), true, NULL, this,
				(std::string(cChannelId) + channel->getName()).c_str(), CRCInput::RC_nokey, NULL,
				channel->scrambled ? NEUTRINO_ICON_SCRAMBLED: (channel->getUrl().empty() ? NULL : NEUTRINO_ICON_STREAMING));
			chan_item->setItemButton(NEUTRINO_ICON_BUTTON_OKAY, true);
			mwtv->addItem(chan_item);

		}
#if 1 // FIXME, probably unneeded by now --martii
		if (g_bouquetManager->Bouquets[i]->Name == "extra.zapit_bouquetname_others"
		 || g_bouquetManager->Bouquets[i]->Name == "extra.zapit_bouquetname_newchannels")
			continue;
#endif
		if(!channels.empty() && (!g_bouquetManager->Bouquets[i]->bHidden ))
		{
			mctv.addItem(new CMenuForwarder(g_bouquetManager->Bouquets[i]->Name, true, NULL, mwtv));
		}
	}
	int res = mctv.exec (NULL, "");

	// delete dynamic created objects
	for(unsigned int count=0;count<toDelete.size();count++)
	{
		delete toDelete[count];
	}
	toDelete.clear();
	return res;
}
//-------------------------------------------------------------------------
// TODO: clean up code
// use templates?
//-------------------------------------------------------------------------
std::string CNeutrinoYParser::func_get_bouquets_with_epg(CyhookHandler *hh, std::string para)
{
	int BouquetNr = 0;
	std::string abnumber, tmp,yresult;
	ZapitChannelList channels;
	//int num;
	int mode = NeutrinoAPI->Zapit->getMode();

	ySplitString(para," ",abnumber, tmp);
	if(!abnumber.empty())
		BouquetNr = atoi(abnumber.c_str());
	if (BouquetNr > 0) {
		BouquetNr--;
#if 0
		channels = mode == CZapitClient::MODE_RADIO ? g_bouquetManager->Bouquets[BouquetNr]->radioChannels : g_bouquetManager->Bouquets[BouquetNr]->tvChannels;
		num = 1 + (mode == CZapitClient::MODE_RADIO ? g_bouquetManager->radioChannelsBegin().getNrofFirstChannelofBouquet(BouquetNr) : g_bouquetManager->tvChannelsBegin().getNrofFirstChannelofBouquet(BouquetNr)) ;
#endif
		if (mode == CZapitClient::MODE_RADIO)
			g_bouquetManager->Bouquets[BouquetNr]->getRadioChannels(channels);
		else
			g_bouquetManager->Bouquets[BouquetNr]->getTvChannels(channels);
	} else {
		CBouquetManager::ChannelIterator cit = mode == CZapitClient::MODE_RADIO ? g_bouquetManager->radioChannelsBegin() : g_bouquetManager->tvChannelsBegin();
		for (; !(cit.EndOfChannels()); cit++)
			channels.push_back(*cit);
		//num = 1;
	}
	NeutrinoAPI->GetChannelEvents();

	int i = 1;
	char classname;
	t_channel_id current_channel = CZapit::getInstance()->GetCurrentChannelID();
	int prozent = 100;
	CSectionsdClient::responseGetCurrentNextInfoChannelID currentNextInfo;
	std::string timestr;
	bool have_logos = false;

	if (!hh->WebserverConfigList["Tuxbox.LogosURL"].empty() && hh->WebserverConfigList["Tuxbox.DisplayLogos"] == "true" )
		have_logos = true;

	for(int j = 0; j < (int) channels.size(); j++)
	{
		CZapitChannel * channel = channels[j];
		CChannelEvent event;
		NeutrinoAPI->GetChannelEvent(channel->getChannelID(), event);

		classname = (i++ & 1) ? 'a' : 'b';
		if (channel->getChannelID() == current_channel)
			classname = 'c';

		std::string bouquetstr = (BouquetNr >= 0) ? ("&amp;bouquet=" + itoa(BouquetNr)) : "";
		yresult += "<tr>";

		if (have_logos) {
			std::string channel_logo = func_get_logo_name(hh, string_printf(PRINTF_CHANNEL_ID_TYPE, channel->getChannelID()));
			std::string zaplink;
			if (channel_logo.empty())
				zaplink = channel->getName().c_str();
			else
				zaplink = string_printf(
						"<img class=\"channel_logo\" src=\"%s\" title=\"%s\" alt=\"%s\" />"
						, channel_logo.c_str()
						, channel->getName().c_str()
						, channel->getName().c_str()
					);

			yresult += string_printf(
					"<td class=\"%c logo_cell %s\" width=\"44\" rowspan=\"2\">"
					"<a href=\"javascript:do_zap('" PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS"')\">"
					"%s"
					"</a>"
					"</td>"
					, classname
					, (channel_logo.empty() ? "no_logo" : "")
					, channel->getChannelID()
					, zaplink.c_str()
					, channel->getName().c_str()
					, channel->getName().c_str()
				);
		}

		/* timer slider */
		if(event.eventID && event.duration > 0)
		{
			prozent = 100 * (time(NULL) - event.startTime) / event.duration;
			yresult += string_printf("<td class=\"%c title_cell\"><table class=\"title_table\" border=\"0\" cellspacing=\"0\" cellpadding=\"3\"><tr><td class=\"cslider_cell\">\n"
					"\t<table border=\"0\" rules=\"none\" class=\"cslider cslider_table\">"
					"<tr>"
					"<td class=\"cslider cslider_used\" width=\"%d\"></td>"
					"<td class=\"cslider cslider_free\" width=\"%d\"></td>"
					"</tr>"
					"</table>\n</td>\n"
					, classname
					, (prozent / 10) * 3
					, (10 - (prozent / 10))*3
				);
		}
		else
		{
			yresult += string_printf("<td class=\"%c title_cell\"><table class=\"title_table\" border=\"0\" cellspacing=\"0\" cellpadding=\"3\"><tr><td class=\"cslider_cell\">\n"
					"\t<table border=\"0\" rules=\"none\" class=\"cslider cslider_table\">"
					"<tr>"
					"<td class=\"cslider cslider_noepg\"></td>"
					"</tr>"
					"</table>\n</td>\n"
					, classname
				);
		}

		/* channel name */
		yresult += "<td>\n";

		if (channel->getChannelID() == current_channel)
			yresult += "<a name=\"akt\"></a>\n";

		yresult += string_printf("<a class=\"clist\" href=\"javascript:do_zap('"PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS"')\">"
				"%d. %s%s"
				"</a>\n"
				, channel->getChannelID()
				, channel->number
				, channel->getName().c_str()
				, (channel->getServiceType() == ST_NVOD_REFERENCE_SERVICE) ? " (NVOD)" : ""
			);

		yresult += "</td>\n";

		/* buttons */
		yresult += "<td align=\"right\" >\n";

		if (channel->getChannelID() == current_channel)
		{
			yresult += "<a href=\"javascript:do_streaminfo()\">";
			yresult += "<img src=\"/images/streaminfo.png\" alt=\"Streaminfo\" title=\"Streaminfo\" />";
			yresult += "</a>\n";
		}

		if (!channel->getUrl().empty())
		{
			yresult += "<img src=\"/images/webtv.png\" alt=\"WebTV\" title=\"WebTV\" />\n";
		}

		if (channel->scrambled)
		{
			yresult += "<img src=\"/images/key.png\" alt=\"Scrambled\" title=\"Scrambled\" />\n";
		}
		if (event.eventID)
		{
			yresult += string_printf("<a href=\"javascript:do_epg('"PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS"','"PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS"')\">"
					"<img src=\"/images/elist.png\" alt=\"Program preview\" title=\"EPG\" />"
					"</a>\n"
					, channel->getChannelID()
					, channel->getChannelID() & 0xFFFFFFFFFFFFULL
				);
		}

		yresult += string_printf("<a href=\"javascript:do_stream('"PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS"','%s')\">"
				"<img src=\"/images/stream.png\" alt=\"Stream\" title=\"Stream\" />"
				"</a>\n"
				, channel->getChannelID()
				, channel->getName().c_str()
			);

		yresult += string_printf("\n&nbsp;&nbsp;<a href=\"/control/build_playlist?id="PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS"\"><img src=\"/images/vlc.png\" alt=\"VLC-Link\" style=\"border: 0px\" /></a>",channel->getChannelID());

		yresult += "</td></tr></table>\n</td>\n</tr>\n";

		if (channel->getServiceType() == ST_NVOD_REFERENCE_SERVICE)
		{
			CSectionsdClient::NVODTimesList nvod_list;
			if (CEitManager::getInstance()->getNVODTimesServiceKey(channel->getChannelID(), nvod_list))
			{
				CZapitClient::subServiceList subServiceList;

				for (CSectionsdClient::NVODTimesList::iterator ni = nvod_list.begin(); ni != nvod_list.end(); ++ni)
				{
					CZapitClient::commandAddSubServices cmd;
					CEPGData epg;

					// Byte Sequence by ntohs
					cmd.original_network_id = ntohs(ni->original_network_id);
					cmd.service_id = ntohs(ni->service_id);
					cmd.transport_stream_id = ntohs(ni->transport_stream_id);

					t_channel_id channel_id = CREATE_CHANNEL_ID(cmd.service_id, cmd.original_network_id, cmd.transport_stream_id);

					timestr = timeString(ni->zeit.startzeit); // FIXME: time is wrong (at least on little endian)!
					CEitManager::getInstance()->getActualEPGServiceKey(channel_id, &epg); // FIXME: der scheissendreck geht nit!!!
					yresult += string_printf("<tr>\n<td align=\"left\" style=\"width: 31px\" class=\"%cepg\">&nbsp;</td>", classname);
					yresult += string_printf("<td class=\"%cepg\">%s&nbsp;", classname, timestr.c_str());
					yresult += string_printf("%s<a href=\"javascript:do_zap('"
							PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS
							")'\">%04x:%04x:%04x %s</a>", // FIXME: get name
							(channel_id == current_channel) ? "<a name=\"akt\"></a>" : " ",
							channel_id,
							bouquetstr.c_str(),
							cmd.transport_stream_id,
							cmd.original_network_id,
							cmd.service_id,
							epg.title.c_str());
					yresult += string_printf("</td>\n</tr>");

					subServiceList.push_back(cmd);
				}

				if (!(subServiceList.empty()))
					NeutrinoAPI->Zapit->setSubServices(subServiceList);
			}
		}

		else if (event.eventID)
		{
			bool has_current_next = true;
			CEitManager::getInstance()->getCurrentNextServiceKey(channel->getEpgID(), currentNextInfo);
			timestr = timeString(event.startTime);

			CShortEPGData epg;
			std::string EPGInfoC = "";
			if (CEitManager::getInstance()->getEPGidShort(currentNextInfo.current_uniqueKey, &epg))
			{
				EPGInfoC += epg.info1;
				EPGInfoC += epg.info2;
			}

			yresult += string_printf("<tr><td class=\"%cepg\">",classname);
			yresult += string_printf("%s&nbsp;<span class='pointer' title='%s'>%s</span>&nbsp;"
					"<span style=\"font-size: 8pt; white-space: nowrap\">(%ld {=L:from=} %d {=L:unit.short.minute=}, %d%%)</span>"
					, timestr.c_str()
					, EPGInfoC.c_str()
					, event.description.c_str()
					, (time(NULL) - event.startTime)/60
					, event.duration / 60,prozent);

			if ((has_current_next) && (currentNextInfo.flags & CSectionsdClient::epgflags::has_next)) {
				std::string EPGInfoN = "";
				if (CEitManager::getInstance()->getEPGidShort(currentNextInfo.next_uniqueKey, &epg))
				{
					EPGInfoN += epg.info1;
					EPGInfoN += epg.info2;
				}
				timestr = timeString(currentNextInfo.next_zeit.startzeit);
				yresult += string_printf("<br />%s&nbsp;<span class='pointer' title='%s'>%s</span>"
						, timestr.c_str()
						, EPGInfoN.c_str()
						, currentNextInfo.next_name.c_str());
			}

			yresult += string_printf("</td></tr>\n");
		}
		else
		yresult += string_printf("<tr><td class=\"%cepg\">&nbsp;<br />&nbsp;</td></tr>\n",classname);
	}
	return yresult;
}