Subversion Repositories HomeAutomation

Rev

Blame | Last modification | View Log | SVN | RSS feed

  1. /*
  2.  * File created by arune
  3.  * at 2004-dec
  4.  */
  5. package Macbeth.Modules.modTVchart;
  6.  
  7. import java.util.*;
  8. import java.net.URL;
  9. import java.io.InputStreamReader;
  10. import java.io.BufferedReader;
  11. //import javax.swing.Timer;
  12. import java.util.Timer;
  13. import java.util.TimerTask;
  14.  
  15. import java.awt.event.*;
  16.  
  17. import Macbeth.System.*;
  18. import Macbeth.Utilities.*;
  19. import Macbeth.XML.XMLDataHandler;
  20.  
  21. /**
  22.  *
  23.  *
  24.  * @author arune
  25.  */
  26. public class modTVchart extends MbModule {
  27.  
  28.     //list of tv-channels and their variables
  29.     private ArrayList channels = new ArrayList();           //a map of channelObjects
  30.     private ArrayList servers = new ArrayList();    //a list of servers
  31.     private int currentServer = -1;     //the serverlist will cycle when connection fails, this var keeps track of current server
  32.     //private HashMap remotebuttons;      //maps remotebutton to tv-channel
  33.     private ArrayList remotebuttons;
  34.     private int currentChannel = 0;     //keeps track of what channel is choosen
  35.     private int lastChannel;            //what number has the last channel (see configfile)
  36.     private int firstChannel;           //what number has the first channel (see configfile)
  37.     private String buttonPplus;         //what button is used for prog+
  38.     private String buttonPminus;        //what button is used for prog-
  39.    
  40.     private Timer requestDataTimer = null;
  41.     private Timer resendMenuTimer = null;
  42.    
  43.     private int timerInterval;
  44.  
  45.     private String currentSubMenu;
  46.     //main
  47.     //SVT1 (longname)
  48.     //SVT2 (longname)
  49.    
  50.     //ArrayList channelChart;
  51.    
  52.     private String menuMiddleId;
  53.    
  54.     //menusystem specific bool, if this submenu is activated
  55.     private boolean activated;
  56.    
  57.     //to check if valid data exist in channelChart
  58.     boolean tvDataSuccess;
  59.     //a date, when data was successfully fetched last
  60.     int lastCheck = 0;
  61.    
  62.     int mainListMode = 1;
  63.    
  64.     //private String lastSend = "";
  65.    
  66.     /**
  67.      * Creates a new instance of modTVchart.
  68.      */
  69.     public modTVchart() {
  70.         //construct MbModule
  71.         super();
  72.         //initial values
  73.  
  74.         //remotebuttons = new HashMap(32);
  75.         remotebuttons = new ArrayList();
  76.        
  77.         //we depend on the RemoteControl-module
  78.         currentSubMenu = "main";
  79.         menuMiddleId = "";
  80.         activated = false;
  81.         //activated = true;
  82.         tvDataSuccess = false;
  83.         timerInterval = 10;
  84.         //activated = true;
  85.  
  86.         //addDependency("RemoteControl");
  87.         //addDependency("MenuSystem");
  88.        
  89.         //register our packet data handler
  90.         setPacketDataHandler(new PacketDataHandler());
  91.     }
  92.  
  93.     public String name() {
  94.         return "TVchart";
  95.     }
  96.  
  97.     public String description() {
  98.         return "Keeps track of current TV channel and outputs information on the TV charts";
  99.     }
  100.  
  101.     /**
  102.      * This method sets default values on all _required_ data
  103.      * fields in the data repository.
  104.      */
  105.     public void initDataFields() {
  106.         //set default values on all REQUIRED option fields before starting up subsystems
  107. //        options.putField("host", "localhost");
  108. //        options.putField("port", "2050");
  109.         //options.putField("checkinterval", "2");
  110.     }
  111.  
  112.     public void startup() throws MbStartupException {
  113.         //startup MbModule
  114.         super.startup();
  115.  
  116.         //get all servers from the data repository
  117.         DataRepository.DataList list = dataRepository.getList("servers");
  118.         if (list!=null) {
  119.             Iterator it = list.items();
  120.             while (it.hasNext()) {
  121.                 DataRepository.DataListItem item = (DataRepository.DataListItem)it.next();
  122.                 String serverlocation = item.getField("serverlocation");
  123.                 servers.add(serverlocation);
  124.             }
  125.         }
  126.  
  127.         //get all remotebuttons from the data repository
  128.         list = dataRepository.getList("remotebtns");
  129.         if (list!=null) {
  130.             Iterator it = list.items();
  131.             while (it.hasNext()) {
  132.                 DataRepository.DataListItem item = (DataRepository.DataListItem)it.next();
  133.                 String remotebutton = item.getField("remotebutton");
  134.                 int tvchannel = Integer.parseInt(item.getField("tvchannel"));
  135.                 //remotebuttons.put(remotebutton, new Integer(tvchannel));
  136.                 remotebuttons.add(new RemoteButton(remotebutton, tvchannel));
  137.             }
  138.         }
  139.  
  140.         //get all channels from the data repository
  141.         list = dataRepository.getList("channels");
  142.         if (list!=null) {
  143.             Iterator it = list.items();
  144.             while (it.hasNext()) {
  145.                 DataRepository.DataListItem item = (DataRepository.DataListItem)it.next();
  146.                 int tvchannel = Integer.parseInt(item.getField("tvchannel"));
  147.                 int id = Integer.parseInt(item.getField("id"));
  148.                 String longname = item.getField("longname");
  149.                 String shortname = item.getField("shortname");
  150.                 channels.add(new ChannelObject(shortname, longname, tvchannel, id));
  151.             }
  152.         }
  153.  
  154.         if (!remotebuttons.isEmpty()) {
  155.             //get p+ / p- buttons, reside under this if because there must be numeric buttons
  156.             buttonPplus = options.getField("progplusbtn");
  157.             buttonPminus = options.getField("progminusbtn");
  158.  
  159.             lastChannel = Integer.parseInt(options.getField("lastchannel"));
  160.             firstChannel = Integer.parseInt(options.getField("firstchannel"));
  161.             currentChannel = firstChannel;
  162.  
  163.             //lets send requests for their remote control buttons
  164.             MbPacket p = new MbPacket();
  165.             p.setDestination(new MbLocation("self", "RemoteControl"));
  166.             //Iterator it = remotebuttons.keySet().iterator();
  167.             for (int i = 0; i < remotebuttons.size(); i++) {
  168.                 String key = ((RemoteButton)remotebuttons.get(i)).remoteButton;
  169.                 p.appendContents("  <buttonrequest button=\"" + key + "\" module=\"" + name() + "\" />");
  170.             }
  171.                
  172.             /*while (it.hasNext()) {
  173.                 String key = (String) it.next();
  174.                 p.appendContents("  <buttonrequest button=\"" + key + "\" module=\"" + name() + "\" />");
  175.             }*/
  176.             p.appendContents("  <buttonrequest button=\"" + buttonPplus + "\" module=\"" + name() + "\" />");
  177.             p.appendContents("  <buttonrequest button=\"" + buttonPminus + "\" module=\"" + name() + "\" />");
  178.  
  179.             sendPacket(p);
  180.         }
  181.        
  182.         //register this module to the displaymodule
  183.         sendToMenuSys("<registersubmod displayname=\"TV Chart\" displaydesc=\"Whats on TV?\" visible=\"true\" />");
  184.  
  185.         //timerInterval = Integer.parseInt(options.getField("checkinterval"));
  186.         if (timerInterval > 0) {
  187.             //TimerListener lyssnare = new TimerListener();
  188.             //TimerTask lyssnare = new TimerTask();
  189.             requestDataTimer = new Timer();
  190.             requestDataTimer.schedule(new DoRequestTask(),1000*60*1,1000*60*timerInterval);
  191.             //requestDataTimer = new Timer(1000*60 * timerInterval, lyssnare);
  192.             //requestDataTimer.start();
  193.         }
  194.  
  195.         resendMenuTimer = new Timer();
  196.         resendMenuTimer.schedule(new DoResendTask(),1000*60*1);
  197.        
  198.         mainListMode = Integer.parseInt(options.getField("mainlistmode"));
  199.     }
  200.  
  201.     public void shutdown() {
  202.         sendToMenuSys("<unregistersubmod />");
  203.         resendMenuTimer.cancel();
  204.         requestDataTimer.cancel();
  205.         super.shutdown();
  206.     }
  207.    
  208.     private void sendActivationReq() {
  209. //      ska be om tillåtelse att få menyn aktiverad
  210.         String dataToSend = "<request />";
  211.        
  212.         //
  213.         sendToMenuSys(dataToSend);
  214.     }
  215.    
  216.     private void sendToMenuSys(String dataToSend) {
  217.         MbPacket p = new MbPacket();
  218.         p.setDestination(new MbLocation("self", "MenuSystem"));
  219.         p.appendContents(dataToSend);
  220.         sendPacket(p);
  221.     }
  222. /*
  223.     private void sendToDisplay(String rowData, int rowNumber) {
  224.         //anropa convertChar här
  225.         rowData = convertText(rowData);
  226.         MbPacket p = new MbPacket();
  227.         //p.setDestination(new MbLocation("self","PacketReceiver"));
  228.         p.setDestination(new MbLocation("self","SmallDisplays"));
  229.         //ARNE packet in XML-format
  230.         p.setContents(" <lcdpacket sender=\"" + name()
  231.                             + "\" type=\"textrow\" prio=\"1\" ttl=\"0\" row=\""
  232.                             + "T+" + rowNumber
  233.                             + "\" id=\"" + 4125882 + rowNumber
  234.                             + "\" data=\"" + convertText(rowData)
  235.                             + "\" />");
  236.       sendPacket(p);
  237.  
  238.     }*/
  239.  
  240.    
  241.     private String getMain() {
  242.         String returnData = "";
  243.         int timeToNextFetch = -1;
  244.         fetchData();
  245.        
  246.         if (!tvDataSuccess) {
  247.             //om det inte finns aktuell data skall vi skicka felmeddelande till displayen
  248.            
  249.         } else {
  250.             String dataToSend = "";
  251.             dataToSend = "<packet menuid=\"MainMenu\"><data>";
  252.             dataToSend = dataToSend + "<middleid>" + menuMiddleId + "</middleid>";
  253.             dataToSend = dataToSend + "<list id=\"menudata\">";
  254.            
  255.             if (channels.size() > 0 && menuMiddleId.equals("")) {
  256.                 ChannelObject o = (ChannelObject)channels.get(0);
  257.                 menuMiddleId = "" + o.id;
  258.             }
  259.            
  260.             Iterator it = channels.iterator();
  261.             //for each channel
  262.             while (it.hasNext()) {
  263.                 ChannelObject o = (ChannelObject)it.next();
  264.                
  265.                 //get tv-chart for current channel
  266.                 ArrayList channelChart = o.channelData;
  267.                 String descr = "";
  268.                 String rightNow = "";
  269.                 //for each show/row on channel
  270.                 for (int i = 0; i < channelChart.size(); i++) {
  271.                     //get row
  272.                     String chartRow = (String)channelChart.get(i);
  273.                     //split it into tokens
  274.                     String[] chartTokens = chartRow.split("\t");
  275.                     int showTime = 0;
  276.                    
  277.                     //int currentHour = Integer.parseInt(MyDateTime.now("HH"));
  278.                     long UTCTime = System.currentTimeMillis();
  279.                     String date = Long.toString(UTCTime);
  280.                     int currentTime = Integer.parseInt(date.substring(0, date.length()-3));
  281.                     if (chartTokens.length >= 3) {
  282.                         showTime = Integer.parseInt(chartTokens[0]);
  283.                         //test if showtime has a completely wrong value (trust no one)
  284.                         if (showTime > currentTime + 24*60*60 || showTime < currentTime - 24*60*60) {
  285.                             break;
  286.                         }
  287.                     }
  288.                     else {
  289.                         break;
  290.                     }
  291.                     String prevChartRow = null;
  292.                     String[] prevChartTokens = null;
  293.                     int prevShowTime = -1;
  294.                     //varför denna och exakt vad bryter den??
  295.                     if (i == 0){// && currentHour < 5) {    //varför hade jag detta???
  296.                         //break;
  297.                     } else if (i != 0) {
  298.                         //makes sure values for previous row is "fresh"
  299.                         prevChartRow = (String)channelChart.get(i-1);
  300.                         prevChartTokens = prevChartRow.split("\t");
  301.                         if (prevChartTokens.length >= 3) {
  302.                             //prevTimeTokens = prevChartTokens[0].split(":");
  303.                             prevShowTime = Integer.parseInt(prevChartTokens[0]);
  304.                             //test if prevShowTime has a completely wrong value
  305.                             if (prevShowTime > currentTime + 24*60*60 || prevShowTime < currentTime - 24*60*60) {
  306.                                 //_debug.println("Break because prevshowtime wrong");
  307.                                 break;
  308.                             }
  309.                         }
  310.                         else {
  311.                             //_debug.println("Break because nr of tokens is wrong");
  312.                             break;
  313.                         }
  314.                     }
  315.                     if (showTime > currentTime) {
  316.                         //testa prevShowTime (om i != 0)
  317.                         //om denna är mindre än currentTime ska den skrivas ut
  318.                         if (i != 0 && prevShowTime < currentTime) {
  319.                            
  320.                             int timeToNextShow = showTime-currentTime;
  321.                             if (timeToNextFetch == -1 || timeToNextShow < timeToNextFetch) {
  322.                                 timeToNextFetch = timeToNextShow+2;
  323.                             }
  324.                            
  325.                             //_debug.println(prevChartTokens[0] + " " + prevChartTokens[1]);
  326.                             //skicka med 0 som rowCounter till funktionen som skriver till display
  327.                             if (mainListMode == 1) {
  328.                                 rightNow = " - " + prevChartTokens[1] + " " + prevChartTokens[2];
  329.                             } else if (mainListMode == 2) {
  330.                                 descr = "Just nu: " + prevChartTokens[1] + " " + prevChartTokens[2] + "&#10;";
  331.                             }
  332.                             if (prevChartTokens.length == 4) {
  333.                                 descr = descr + prevChartTokens[3]+ "&#10;&#10;";
  334.                             } else if (mainListMode == 2) {
  335.                                 descr = descr + "&#10;";
  336.                             }
  337.                             descr = descr + "H&#228;rn&#228;st: " + chartTokens[1] + " " + chartTokens[2];
  338.                             if (chartTokens.length == 4) {
  339.                                 descr = descr + "&#10;" + chartTokens[3];
  340.                             }
  341.                             break;
  342.                         } else if (i == 0) {
  343.                             descr = "H&#228;rn&#228;st: " + chartTokens[1] + " " + chartTokens[2];
  344.                         }
  345.                     }                    
  346.                 }
  347.                 dataToSend = dataToSend + "<item id=\"" + o.id + "\" title=\"" + o.longname + rightNow + "\" desc=\"" + descr + "\" />";
  348.             }
  349.            
  350.             dataToSend = dataToSend + "</list>";
  351.             dataToSend = dataToSend + "</data></packet>";
  352.             //sendToMenuSys(dataToSend);
  353.             returnData = dataToSend;
  354.         }
  355.         if (timeToNextFetch == -1) {
  356.             timeToNextFetch = 1800;
  357.         }
  358.         if (timeToNextFetch < 30) {
  359.             timeToNextFetch = 30;
  360.         }
  361.         if (timeToNextFetch > 3600) {
  362.             timeToNextFetch = 3600;
  363.         }
  364.         //_debug.println("Main: scheduling timer, timeToNextFetch: " + timeToNextFetch);
  365.         resendMenuTimer.cancel();
  366.         resendMenuTimer = new Timer();
  367.         resendMenuTimer.schedule(new DoResendTask(),timeToNextFetch*1000);
  368.        
  369.         return returnData;
  370.     }
  371.  
  372.     private String getSub(String id) {
  373.         String returnData = "";
  374.         int timeToNextFetch = -1;
  375.         fetchData();
  376.         if (!tvDataSuccess) {
  377.             //om det inte finns aktuell data skall vi skicka felmeddelande till displayen
  378.             //returnData = ...
  379.         } else {
  380.            
  381.             //om det finns aktuell data
  382.             String dataToSend = "";
  383.             dataToSend = "<packet menuid=\"MainMenu\"><data>";
  384.                
  385.                 //ChannelObject o = (ChannelObject)it.next();
  386.             ArrayList channelChart = new ArrayList();
  387.             Iterator it = channels.iterator();
  388.             while (it.hasNext()) {
  389.                 ChannelObject o = (ChannelObject)it.next();
  390.                 if (id.equals("" + o.id)) {
  391.                     channelChart = o.channelData;
  392.                     break;
  393.                 }
  394.             }
  395.            
  396.             if (channelChart.size() > 0) {
  397.                 //ArrayList channelChart = getWebPage(id);
  398.                 String itemlist = "";
  399.                 int current = 0;
  400.                
  401.                 for (int i = 0; i < channelChart.size(); i++) {
  402.                     String chartRow = (String)channelChart.get(i);
  403.                     String[] chartTokens = chartRow.split("\t");
  404.                     int showTime = 0;
  405.                    
  406.                     int currentHour = Integer.parseInt(MyDateTime.now("HH"));
  407.                     long UTCTime = System.currentTimeMillis();
  408.                     String date = Long.toString(UTCTime);
  409.                     int currentTime = Integer.parseInt(date.substring(0, date.length()-3));
  410.                     if (chartTokens.length >= 3) {
  411.                         showTime = Integer.parseInt(chartTokens[0]);
  412.                         //test if showtime has a completely wrong value (trust no one)
  413.                         if (showTime > currentTime + 24*60*60 || showTime < currentTime - 24*60*60) {
  414.                             break;
  415.                         }
  416.                     }
  417.                     else {
  418.                         break;
  419.                     }
  420.                     String prevChartRow = null;
  421.                     String[] prevChartTokens = null;
  422.                     int prevShowTime = -1;
  423.                     if (i == 0 && currentHour < 5) {
  424.                         //break;
  425.                     } else if (i != 0) {
  426.                         prevChartRow = (String)channelChart.get(i-1);
  427.                         prevChartTokens = prevChartRow.split("\t");
  428.                         if (prevChartTokens.length >= 3) {
  429.                             //prevTimeTokens = prevChartTokens[0].split(":");
  430.                             prevShowTime = Integer.parseInt(prevChartTokens[0]);
  431.                             //test if prevShowTime has a completely wrong value
  432.                             if (prevShowTime > currentTime + 24*60*60 || prevShowTime < currentTime - 24*60*60) {
  433.                                 break;
  434.                             }
  435.                         }
  436.                         else {
  437.                             break;
  438.                         }
  439.                     }
  440.                    
  441.                     String descr = "";
  442.                     if (chartTokens.length == 4) {
  443.                         descr = chartTokens[3];
  444.                     }
  445.                    
  446.                     itemlist = itemlist + "<item id=\"" + i + "\" title=\"" + chartTokens[1] + " " + chartTokens[2] + "\" desc=\"" + descr + "\" />";
  447.                     if (showTime > currentTime) {
  448.                         //om denna är mindre än currentTime ska den skrivas ut
  449.                         if (i != 0 && prevShowTime < currentTime) {
  450.                             current = i-1;
  451.                         }
  452.  
  453.                         int timeToNextShow = showTime-currentTime;
  454.                         if (timeToNextFetch == -1 || timeToNextShow < timeToNextFetch) {
  455.                             timeToNextFetch = timeToNextShow+2;
  456.                         }
  457.                     }                    
  458.                 }
  459.                 dataToSend = dataToSend + "<middleid>" + current + "</middleid>";
  460.                 dataToSend = dataToSend + "<list id=\"menudata\">";
  461.                 dataToSend = dataToSend + itemlist;
  462.                
  463.                 dataToSend = dataToSend + "</list>";
  464.                 dataToSend = dataToSend + "</data></packet>";
  465.                
  466.                 returnData = dataToSend;
  467.                 //sendToMenuSys(dataToSend);
  468.             }  
  469.         }
  470.        
  471.         if (timeToNextFetch == -1) {
  472.             timeToNextFetch = 1800;
  473.         }
  474.         if (timeToNextFetch < 30) {
  475.             timeToNextFetch = 30;
  476.         }
  477.         if (timeToNextFetch > 3600) {
  478.             timeToNextFetch = 3600;
  479.         }
  480.         //_debug.println("Sub: scheduling timer, timeToNextFetch: " + timeToNextFetch);
  481.         resendMenuTimer.cancel();
  482.         resendMenuTimer = new Timer();
  483.         resendMenuTimer.schedule(new DoResendTask(),timeToNextFetch*1000);
  484.  
  485.         return returnData;
  486.     }
  487.  
  488.     private String getServerURL() {
  489.         if (currentServer == -1) {
  490.             if (servers.size() == 0) {
  491.                 return ""; }
  492.             else {
  493.                 currentServer = 0; }
  494.         } else {
  495.             //currentServer räknas upp i catch:en nedan
  496.         }
  497.         if (currentServer >= servers.size()) {
  498.             currentServer = 0; }
  499.         return (String)servers.get(currentServer);
  500.     }
  501.    
  502.     private boolean fetchData() {
  503.         int currentHour = Integer.parseInt(MyDateTime.now("HH"));
  504.         long UTCTime = System.currentTimeMillis();
  505.         String date = Long.toString(UTCTime);
  506.         int currentTime = Integer.parseInt(date.substring(0, date.length()-3));
  507.         boolean didFetch = false;
  508.         //TODO: Vad gör denna för nytta egentilgen?
  509.         //if (currentTime > lastCheck+12*60*60) {
  510.         //  tvDataSuccess = false;
  511.         //}
  512.        
  513.         if ((currentHour == 6 && currentTime > lastCheck+60*60) || !tvDataSuccess) {
  514.             //incase the server does not respond this var should be false
  515.             tvDataSuccess = false;
  516.            
  517.             Iterator it = channels.iterator();
  518.             boolean dataError = false;
  519.             while (it.hasNext()) {
  520.                 ChannelObject o = (ChannelObject)it.next();
  521.                 o.channelData = getWebPage("" + o.id);
  522.                 if (o.channelData == null) {
  523.                     dataError = true;
  524.                     o.channelData = new ArrayList();
  525.                 }
  526.             }
  527.            
  528.             if (!dataError) {
  529.                 lastCheck = currentTime;
  530.                 tvDataSuccess = true;
  531.                 didFetch = true;
  532.             }
  533.         }
  534.        
  535.         return didFetch;
  536.        
  537.     }
  538.    
  539.     private ArrayList getWebPage(String id) {
  540.         ArrayList rowStrings = null; //new ArrayList();
  541.  
  542.         String serverURL = getServerURL();
  543.  
  544.         if (!serverURL.equals("")) {
  545.             serverURL = serverURL + "/index.php?id=" + id;
  546.             try {
  547.                 BufferedReader page = new BufferedReader(new InputStreamReader(new URL(serverURL).openStream()));
  548.                
  549.                 rowStrings = new ArrayList();
  550.                 String curLine = page.readLine();
  551.                 while ( curLine != null ) {
  552.                     rowStrings.add(curLine);
  553.                     // get the next line
  554.                     curLine = page.readLine();
  555.                 }
  556.             }
  557.             catch ( Exception ex ){
  558.                 _errors.println("Comunication problem with tv-chart-server, exception: " + ex.getMessage());
  559.                 currentServer++;
  560.             }
  561.         }
  562.  
  563.         return rowStrings;
  564.     }
  565.  
  566.     /**
  567.      * Takes care of XML-data found in incoming packets.
  568.      */
  569.     private class PacketDataHandler implements XMLDataHandler {
  570.         public void XMLstartElement(String element, HashMap attributes) {
  571.             if (element.equals("activate")) {
  572.                 //menusystem activates this submenu
  573.                 //we should send a menu to display
  574.                 activated = true;
  575.                 if (currentSubMenu.equals("main")) {
  576.                     String dataToSend = getMain();
  577.                     sendToMenuSys(dataToSend);
  578.                 } else {
  579.                     String dataToSend = getSub(menuMiddleId);
  580.                     sendToMenuSys(dataToSend);
  581.                 }
  582.                
  583.             } else if (element.equals("refresh")) {
  584.                 //menusystem wants a refreshed menu
  585.                  if (currentSubMenu.equals("main")) {
  586.                     String dataToSend = getMain();
  587.                     sendToMenuSys(dataToSend);
  588.                 } else {
  589.                     String dataToSend = getSub(menuMiddleId);
  590.                     sendToMenuSys(dataToSend);
  591.                 }
  592.                  
  593.             } else if (element.equals("deactivate")) {
  594.                 //menusystem deactivates this submenu
  595.                 activated = false;
  596.                 //resendMenuTimer.cancel();
  597.                  
  598.             } else if (element.equals("padLeft") && attributes.containsKey("state") && attributes.containsKey("level")) {
  599.                 //user pressed padleft on his remote
  600.                 //we should traverse back one step or deactivate
  601.                 //if we are in submenu root
  602.                 String state = (String)attributes.get("state");
  603.                 int level = Integer.parseInt((String)attributes.get("level"));
  604.                 if (level >= 1) {
  605.                     if (state.equals("DOWN")) {
  606.                         if (currentSubMenu.equals("main")) {
  607.                             activated = false;
  608.                             //resendMenuTimer.cancel();
  609.                             sendToMenuSys("<deactivates />");
  610.                         } else {
  611.                             currentSubMenu = "main";
  612.                             String dataToSend = getMain();
  613.                             sendToMenuSys(dataToSend);
  614.                         }
  615.                     }
  616.                 }
  617.             } else if (element.equals("padRight") && attributes.containsKey("state") && attributes.containsKey("level")) {
  618.                 String state = (String)attributes.get("state");
  619.                 int level = Integer.parseInt((String)attributes.get("level"));
  620.                 //user pressed padright on his remote
  621.                 //we should traverse forward one step
  622.                 if (level >= 1) {
  623.                     if (state.equals("DOWN")) {
  624.                         if (currentSubMenu.equals("main")) {
  625.                             String dataToSend = getSub(menuMiddleId);
  626.                             sendToMenuSys(dataToSend);
  627.  
  628.                             currentSubMenu = menuMiddleId;
  629.                         }
  630.                     }
  631.                 }
  632.                
  633.             } else if (element.equals("padUp") && attributes.containsKey("state") && attributes.containsKey("level")) {
  634.                 //user pressed padright on his remote
  635.                 //we should traverse forward one step
  636.                 String state = (String)attributes.get("state");
  637.                 int level = Integer.parseInt((String)attributes.get("level"));
  638.                
  639.                 if (level >= 2) {
  640.                     if (state.equals("DOWN")) {
  641.                         sendToMenuSys("<packet menuid=\"MainMenu\"><command><scroll>1</scroll></command></packet>");
  642.                     } else {
  643.                         sendToMenuSys("<packet menuid=\"MainMenu\"><command><scroll>0</scroll></command></packet>");
  644.                     }
  645.                 }
  646.  
  647.             } else if (element.equals("padDown") && attributes.containsKey("state") && attributes.containsKey("level")) {
  648.                 //user pressed padright on his remote
  649.                 //we should traverse forward one step
  650.                 String state = (String)attributes.get("state");
  651.                 int level = Integer.parseInt((String)attributes.get("level"));
  652.                
  653.                 if (level >= 2) {
  654.                     if (state.equals("DOWN")) {
  655.                         sendToMenuSys("<packet menuid=\"MainMenu\"><command><scroll>-1</scroll></command></packet>");
  656.                     } else {
  657.                         sendToMenuSys("<packet menuid=\"MainMenu\"><command><scroll>0</scroll></command></packet>");
  658.                     }
  659.                 }
  660.                
  661.             } else if (element.equals("padOk") && attributes.containsKey("state") && attributes.containsKey("level")) {
  662.                 //user pressed padOk on his remote
  663.                 String state = (String)attributes.get("state");
  664.                 int level = Integer.parseInt((String)attributes.get("level"));
  665.                     //state=\"UP\"
  666.                 if (level >= 3) {
  667.                     if (state.equals("DOWN")) {
  668.                         if (currentSubMenu.equals("main")) {
  669.                             int curChan = -1;
  670.                             for (int i = 0; i < channels.size(); i++) {
  671.                                 if (menuMiddleId.equals("" + ((ChannelObject)channels.get(i)).id)) {
  672.                                     curChan = ((ChannelObject)channels.get(i)).tvchannel;
  673.                                 }
  674.                             }
  675.                             if (curChan != -1) {
  676.                                 for (int i = 0; i < remotebuttons.size(); i++) {
  677.                                     String key = ((RemoteButton)remotebuttons.get(i)).remoteButton;
  678.                                     int remoteChan = ((RemoteButton)remotebuttons.get(i)).channel;
  679.                                    
  680.                                     if (curChan == remoteChan) {
  681.                                         currentChannel = curChan;
  682.                                         MbPacket p = new MbPacket();
  683.                                         p.setDestination(new MbLocation("self", "GenRoomControl"));
  684.                                         p.appendContents("<remotecontrol button=\"" + key + "\" state=\"DOWN\" />");
  685.                                         sendPacket(p);
  686.                                         try {
  687.                                             Thread.sleep(120);                                 
  688.                                         } catch (InterruptedException ex) {
  689.                                         }
  690.                                         p = new MbPacket();
  691.                                         p.setDestination(new MbLocation("self", "GenRoomControl"));
  692.                                         p.appendContents("<remotecontrol button=\"" + key + "\" state=\"UP\" />");
  693.                                         sendPacket(p);
  694.                                        
  695.                                         /*
  696.                                          * 2006-01-30 20:34 Jimmy: det bör inte vara några problem.
  697.                                          * modulerna körs ju i egna trådar (om jag inte minns helt fel),
  698.                                          * så det går väl i princip göra Thread.Sleep eller vad det nu
  699.                                          * kan tänkas heta
  700.                                          */
  701.                                     }
  702.                                 }
  703.                             }
  704.                         } else if (state.equals("UP")) {
  705.                             //knappen släpptes efter 120us, se ovan
  706.                         }
  707.                     }
  708.                 }
  709.             } else if (element.equals("middleid") && attributes.containsKey("value") && attributes.containsKey("menuid") && attributes.containsKey("userlevel")) {
  710.                 //menuMiddleId = (String)attributes.get("value");
  711.                 String middleId = (String)attributes.get("value");
  712.                 String menuId = (String)attributes.get("menuid");
  713.                 int userlevel = 0;
  714.                 try {
  715.                     userlevel = Integer.parseInt((String)attributes.get("userlevel"));
  716.                    
  717.                 } catch (NumberFormatException ex) {
  718.                     _errors.println("There was a faulty userlevel sent to me: " + (String)attributes.get("userlevel"));
  719.                 }
  720.  
  721.                 if (currentSubMenu.equals("main") && userlevel >= 2 && menuId.equals("MainMenu")) {
  722.                     menuMiddleId = middleId;
  723.                 }              
  724.                
  725.                 /* Ex: <remotecontrol button="NUMERIC4" state="DOWN" />
  726.                  * This is a notification from the remote control module
  727.                  * about one of our requested remote control buttons have
  728.                  * been pressed. */        
  729.             } else if (element.equals("remotecontrol") && attributes.containsKey("button") && attributes.containsKey("state")) {
  730.                 String state = (String)attributes.get("state");
  731.                 String button = (String)attributes.get("button");
  732.                 if (state.equals("DOWN")) {
  733.                     boolean update = false;
  734.                     if (buttonPplus.equals(button)) {
  735.                         currentChannel++;
  736.                         update = true;
  737.                         if (currentChannel > lastChannel) {
  738.                             currentChannel = firstChannel;
  739.                         }
  740.                         //updateDisplay();
  741.                     }
  742.                     // P+ och P- ska egentligen hoppa till nästa/föregående kanal
  743.                     // dessa behöver inte ligga efter varandra
  744.                     else if (buttonPminus.equals(button)) {
  745.                         currentChannel--;
  746.                         update = true;
  747.                         if (currentChannel < firstChannel) {
  748.                             currentChannel = lastChannel;
  749.                         }
  750.                         //updateDisplay();
  751.                     }
  752.                     else {
  753.                         //find channel that is associated with this remote button
  754.                         for (int i = 0; i < remotebuttons.size(); i++) {
  755.                             String key = ((RemoteButton)remotebuttons.get(i)).remoteButton;
  756.                             int channel = ((RemoteButton)remotebuttons.get(i)).channel;
  757.                             if (key.equals(button)) {
  758.                                 if (currentChannel != channel) {      //only update on changed channel
  759.                                     currentChannel = channel;
  760.                                     update = true;
  761.                                 } // update not only on changed channel, one might want to update the info on the display
  762.                             }
  763.                         }
  764.                     }
  765.                     if (update) {
  766.                         for (int i = 0; i < channels.size(); i++) {
  767.                             if (((ChannelObject)channels.get(i)).tvchannel == currentChannel) {
  768.                                 menuMiddleId = "" + ((ChannelObject)channels.get(i)).id;
  769.                             }
  770.                         }
  771.                        
  772.                         if (currentSubMenu.equals("main") && activated) {
  773.                             String dataToSend = getMain();
  774.                             sendToMenuSys(dataToSend);
  775.                             //TODO: egentligen ska vi bara skicka gotorow=menuMiddleId
  776.                             //men flinsh stödjer inte det än
  777.                         } else {
  778.                             //TODO: annars ska man väl skicka kommando till menusystem att vi
  779.                             //vill outa saker på display
  780.                             sendActivationReq();    //ska be om tillåtelse att få menyn aktiverad
  781.                         }
  782.                     }
  783.                 }
  784.                 else if (state.equals("UP")) {
  785.                     //send btn-release-message to RMP (5000)
  786. //                    sendString("5000");
  787.                 }
  788.             }
  789.         }
  790.  
  791.         public void XMLendElement(String element) {}
  792.         public void XMLelementData(String data) {}
  793.         public void XMLdocumentStart() {}
  794.         public void XMLdocumentEnd() {}
  795.     }
  796.    
  797.     //En lyssnare för timern
  798.     /**
  799.      * Timer handles datafetch from tv-server
  800.      */
  801.     /*private class TimerListener implements ActionListener {
  802.         public void actionPerformed(ActionEvent e) {
  803.             if (fetchData()) {
  804.                 //if tv-chart was downloaded then
  805.                 //renew menus
  806.  
  807.                 if (activated) {
  808.                     if (currentSubMenu.equals("main")) {
  809.                         //sendMain();
  810.                         String dataToSend = getMain();
  811.                         //if (!lastSend.equals(dataToSend)) {
  812.                         sendToMenuSys(dataToSend);
  813.                         //}
  814.                         //lastSend = dataToSend;
  815.                     } else {
  816.                         //sendSub(menuMiddleId);
  817.                         String dataToSend = getSub(menuMiddleId);
  818.                         //if (!lastSend.equals(dataToSend)) {
  819.                         sendToMenuSys(dataToSend);
  820.                         //}
  821.                         //lastSend = dataToSend;
  822.                     }
  823.                 }
  824.             }
  825.         }
  826.     }*/
  827.    
  828.     /**
  829.      * Timer handles datafetch from tv-server
  830.      */
  831.     private class DoRequestTask extends TimerTask {
  832.         public void run() {
  833.             //_debug.println("DoRequestTask now");
  834.             if (fetchData()) {
  835.                 //_debug.println("Got new data");
  836.                 //if tv-chart was downloaded then
  837.                 //renew menus
  838.  
  839.                 if (activated) {
  840.                     if (currentSubMenu.equals("main")) {
  841.                         //sendMain();
  842.                         String dataToSend = getMain();
  843.                         sendToMenuSys(dataToSend);
  844.                     } else {
  845.                         //sendSub(menuMiddleId);
  846.                         String dataToSend = getSub(menuMiddleId);
  847.                         sendToMenuSys(dataToSend);
  848.                     }
  849.                 }
  850.             }
  851.  
  852.         }
  853.     }
  854.    
  855.     private class DoResendTask extends TimerTask {
  856.         public void run() {
  857.             //_debug.println("DoResendTask now");
  858.             //resendMenuTimer.cancel();
  859.             //renew menus
  860.            
  861.             if (activated) {        //we may have left this menu
  862.                 if (currentSubMenu.equals("main")) {
  863.                     //sendMain();
  864.                     String dataToSend = getMain();
  865.                     sendToMenuSys(dataToSend);
  866.                 } else {
  867.                     //sendSub(menuMiddleId);
  868.                     String dataToSend = getSub(menuMiddleId);
  869.                     sendToMenuSys(dataToSend);
  870.                 }
  871.             }
  872.         }
  873.     }
  874.    
  875.     private class RemoteButton {
  876.        
  877.         public String remoteButton;
  878.         public int channel;
  879.  
  880.         /**
  881.          * Creates a new instance of RemoteButton.
  882.          */
  883.         public RemoteButton(String remoteButton, int channel) {
  884.             this.remoteButton = remoteButton;
  885.             this.channel = channel;
  886.         }
  887.  
  888.     }
  889.    
  890.  
  891. }