
        return t;
    }

    private void crearMenusLaterales() {
        guideMenu = new LinearLayout(this);
        guideMenu.setOrientation(LinearLayout.HORIZONTAL);
        guideMenu.setPadding(18, 18, 18, 18);
        guideMenu.setVisibility(View.GONE);
        guideMenu.setBackground(fondoMenu(70));

        LinearLayout colCanales = new LinearLayout(this);
        colCanales.setOrientation(LinearLayout.VERTICAL);
        TextView h1 = itemMenu(catName, true, 18);
        colCanales.addView(h1);

        if (channelItems.size() > 0) {
            int chStart = Math.max(0, focusedChannelIndex - (maxVisibleChannels / 2));
            if (chStart + maxVisibleChannels > channelItems.size()) chStart = Math.max(0, channelItems.size() - maxVisibleChannels);

            for (int i = chStart; i < channelItems.size() && i < chStart + maxVisibleChannels; i++) {
                ChannelItem ch = channelItems.get(i);
                boolean foco = i == focusedChannelIndex;
                colCanales.addView(canalItem(ch, foco));
            }
        } else {
            for (int i = 1; i <= 9; i++) {
                String txt = (i == 1 ? "▶ " : "   ") + (i == 1 ? channelName : "Canal " + i);
                colCanales.addView(itemMenu(txt, i == 1, 17));
            }
        }

        ChannelItem focoCh = canalEnFoco();

        String guiaNombre = channelName;
        String guiaNow = nowTitle;
        String guiaNext = nextTitle;
        String guiaSt = startTime;
        String guiaEn = endTime;
        String guiaNs = nextStartTime;
        String guiaNe = nextEndTime;

        if (focoCh != null) {
            guiaNombre = focoCh.name;
            guiaNow = (focoCh.now == null || focoCh.now.trim().isEmpty()) ? "Programación en Actualización" : focoCh.now;
            guiaNext = (focoCh.next == null || focoCh.next.trim().isEmpty()) ? "Programación en Actualización" : focoCh.next;
            guiaSt = focoCh.st == null ? "" : focoCh.st;
            guiaEn = focoCh.en == null ? "" : focoCh.en;
            guiaNs = focoCh.ns == null ? "" : focoCh.ns;
            guiaNe = focoCh.ne == null ? "" : focoCh.ne;
        }

        LinearLayout colProg = new LinearLayout(this);
        colProg.setOrientation(LinearLayout.VERTICAL);
        colProg.addView(itemMenu("Programación 24h - " + guiaNombre, false, 19));

        if (focoCh != null && focoCh.programs != null && focoCh.programs.size() > 0) {
            int maxProg = Math.min(14, focoCh.programs.size());
            for (int i = 0; i < maxProg; i++) {
                EpgItem ep = focoCh.programs.get(i);
                boolean actual = false;
                try {
                    long nowTs = System.currentTimeMillis() / 1000L;
                    actual = nowTs >= ep.start && nowTs < ep.stop;
                } catch(Exception ignored) {}

                String linea = horaBonita(String.valueOf(ep.start)) + "   " + ep.title;
                colProg.addView(itemMenu(linea, actual, 14));
            }
        } else {
            colProg.addView(itemMenu(horaBonita(guiaSt) + "   " + guiaNow, true, 14));
            colProg.addView(itemMenu(horaBonita(guiaNs) + "   " + guiaNext, false, 14));
        }

        LinearLayout colDetalle = new LinearLayout(this);
        colDetalle.setOrientation(LinearLayout.VERTICAL);
        colDetalle.addView(itemMenu("Detalle programa", false, 19));
        colDetalle.addView(itemMenu(guiaNow, true, 15));
        colDetalle.addView(itemMenu(formatoHorario(guiaSt, guiaEn), false, 13));
        colDetalle.addView(itemMenu(minutosRestantes(guiaEn), false, 13));
        colDetalle.addView(itemMenu("Canal: " + guiaNombre, false, 13));

        guideMenu.addView(colCanales, new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 34));

        View sepGuide1 = new View(this);
        sepGuide1.setBackgroundColor(Color.argb(55, 0, 210, 255));
        guideMenu.addView(sepGuide1, new LinearLayout.LayoutParams(10, LinearLayout.LayoutParams.MATCH_PARENT));

        guideMenu.addView(colProg, new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 40));

        View sepGuide2 = new View(this);
        sepGuide2.setBackgroundColor(Color.argb(55, 0, 210, 255));
        guideMenu.addView(sepGuide2, new LinearLayout.LayoutParams(10, LinearLayout.LayoutParams.MATCH_PARENT));

        guideMenu.addView(colDetalle, new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 26));

        FrameLayout.LayoutParams gp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
        gp.gravity = Gravity.LEFT;
        gp.setMargins(24, 32, 24, 34);
        root.addView(guideMenu, gp);

        catMenu = new LinearLayout(this);
        catMenu.setOrientation(LinearLayout.HORIZONTAL);
        catMenu.setPadding(18, 18, 18, 18);
        catMenu.setVisibility(View.GONE);
        catMenu.setBackground(fondoMenu(70));

        LinearLayout colCats = new LinearLayout(this);
        colCats.setOrientation(LinearLayout.VERTICAL);
        colCats.addView(itemMenu("CATEGORIAS", catActiveColumn == 0, 18));
        if (categoryItems.size() > 0) {
            int catStart = Math.max(0, focusedCategoryIndex - (maxVisibleCats / 2));
            if (catStart + maxVisibleCats > categoryItems.size()) catStart = Math.max(0, categoryItems.size() - maxVisibleCats);

            for (int i = catStart; i < categoryItems.size() && i < catStart + maxVisibleCats; i++) {
                boolean focoCat = (catActiveColumn == 0 && i == focusedCategoryIndex);
                colCats.addView(itemMenu((focoCat ? "▶ " : "   ") + categoryItems.get(i).name, focoCat, 16));
            }
        } else {
            colCats.addView(itemMenu("   Cargando categorías...", false, 16));
        }

        LinearLayout colCatChannels = new LinearLayout(this);
        colCatChannels.setOrientation(LinearLayout.VERTICAL);
        colCatChannels.addView(itemMenu(catName, catActiveColumn == 1, 18));
        if (channelItems.size() > 0) {
            int chCatStart = Math.max(0, focusedChannelIndex - (maxVisibleChannels / 2));
            if (chCatStart + maxVisibleChannels > channelItems.size()) chCatStart = Math.max(0, channelItems.size() - maxVisibleChannels);

            for (int i = chCatStart; i < channelItems.size() && i < chCatStart + maxVisibleChannels; i++) {
                ChannelItem ch = channelItems.get(i);
                    reconstruirMenus();
                    if (menuState == 1 && guideMenu != null) guideMenu.setVisibility(View.VISIBLE);
                    if (menuState == 2 && catMenu != null) catMenu.setVisibility(View.VISIBLE);
                    cargarEpgCanalEnfocado();
                });

            } catch(Exception ignored) {
            } finally {
                focusedEpgLoading = false;
            }
        }).start();
    }


    private void moverCanalFoco(int delta) {
        if (channelItems == null || channelItems.size() == 0) return;

        focusedChannelIndex += delta;
        if (focusedChannelIndex < 0) focusedChannelIndex = 0;
        if (focusedChannelIndex >= channelItems.size()) focusedChannelIndex = channelItems.size() - 1;

        reconstruirMenus();

        if (menuState == 1 && guideMenu != null) guideMenu.setVisibility(View.VISIBLE);
        if (menuState == 2 && catMenu != null) catMenu.setVisibility(View.VISIBLE);

        cargarEpgCanalEnfocado();
    }


    private static class EpgItem {
        String title = "";
        String desc = "";
        long start = 0;
        long stop = 0;
    }

    private void cargarEpgUnaVez() {
        new Thread(() -> {
            try {
                String api;
                if (streamId != null && streamId.trim().length() > 0) {
                    api = "http://216.152.155.250/PUNTOZ_PANEL/tv_clean.php?ajax_epg=1&stream_id=" + URLEncoder.encode(streamId, "UTF-8");
                } else {
                    api = "http://216.152.155.250/PUNTOZ_PANEL/pz_epg_api.php?channel=" + URLEncoder.encode(channelName, "UTF-8");
                }
                URL u = new URL(api);
                HttpURLConnection c = (HttpURLConnection) u.openConnection();
                c.setConnectTimeout(6000);
                c.setReadTimeout(10000);
                c.setRequestProperty("User-Agent", "Puntoz-TV-Android");
69:    int focusedChannelIndex = 0;
74:    int maxVisibleChannels = 18;
146:                focusedChannelIndex = i;
357:            int chStart = Math.max(0, focusedChannelIndex - (maxVisibleChannels / 2));
358:            if (chStart + maxVisibleChannels > channelItems.size()) chStart = Math.max(0, channelItems.size() - maxVisibleChannels);
360:            for (int i = chStart; i < channelItems.size() && i < chStart + maxVisibleChannels; i++) {
362:                boolean foco = i == focusedChannelIndex;
396:        if (focoCh != null && focoCh.programs != null && focoCh.programs.size() > 0) {
397:            int maxProg = Math.min(14, focoCh.programs.size());
398:            for (int i = 0; i < maxProg; i++) {
466:            int chCatStart = Math.max(0, focusedChannelIndex - (maxVisibleChannels / 2));
467:            if (chCatStart + maxVisibleChannels > channelItems.size()) chCatStart = Math.max(0, channelItems.size() - maxVisibleChannels);
469:            for (int i = chCatStart; i < channelItems.size() && i < chCatStart + maxVisibleChannels; i++) {
471:                boolean foco = (catActiveColumn == 1 && i == focusedChannelIndex);
523:                focusedChannelIndex = i;
539:        focusedChannelIndex = playingChannelIndex;
583:                focusedChannelIndex = i;
638:                focusedChannelIndex = i;
644:        if (!foundPlaying) focusedChannelIndex = 0;
722:                            focusedChannelIndex = k;
728:                    if (!foundPlaying && focusedChannelIndex >= channelItems.size()) {
729:                        focusedChannelIndex = 0;
759:        focusedChannelIndex = 0;
806:    private void cargarLogoEn(ImageView img, String logoUrl) {
872:        // cargarLogoEn(logo, ch.logo); DESACTIVADO TEST VELOCIDAD MENU
949:        if (focusedChannelIndex < 0) focusedChannelIndex = 0;
950:        if (focusedChannelIndex >= channelItems.size()) focusedChannelIndex = channelItems.size() - 1;
951:        return channelItems.get(focusedChannelIndex);
1032:        focusedChannelIndex += delta;
1033:        if (focusedChannelIndex < 0) focusedChannelIndex = 0;
1034:        if (focusedChannelIndex >= channelItems.size()) focusedChannelIndex = channelItems.size() - 1;
