Subversion Repositories HomeAutomation

Rev

Go to most recent revision | Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
15 arune 1
/*
2
 * File created by arune
3
 * at 2005-jan-09 16:54:44
4
 */
5
package Macbeth.Modules.modMenuSystem;
6
 
7
import Macbeth.System.*;
8
import Macbeth.Utilities.*;
9
import Macbeth.XML.XMLDataHandler;
10
import Macbeth.XML.XMLParser;
11
import Macbeth.Utilities.*;
12
import Macbeth.Modules.modGenRoomControl.GenRoomObject;
13
import Macbeth.Net.*;
14
 
15
import java.util.*;
16
 
17
import javax.swing.*;
18
import javax.swing.Timer;
19
 
20
import org.xml.sax.SAXException;
21
 
22
import java.awt.event.*;
23
import java.io.IOException;
24
 
25
/**
26
 * This is the core of the menusystem, this module should register
27
 * the Pad-, Ok- and Cancel/back/menu-buttons from remotecontrol.
28
 * Other submenumodules can register to this module.
29
 * Submenumodules get (if they need) a row in the root menu.
30
 * The user navigates the rootmenu with the pad-buttons, when selecting one
31
 * row with pad-right or ok then this choosen submenu should send its root-menu
32
 * to menusystem and it sends it to be displayed, menusystem should also
33
 * send the pad-buttons to this submenu.
34
 *
35
 * for now...
36
 *
37
 * @author arune
38
 */
39
public class modMenuSystem extends MbModule implements ServerDataHandler{
40
 
41
private XMLDataHandler flinshDataHandler;
42
//private XMLParser packetXMLParser;
43
 
44
private TcpServer flinshServer;
45
//private Timer requestDataTimer = null;
46
//private int timerInterval = 0;
47
private final char EOF = (char) 0x00;
48
//A table containing all registered modules (submenus and vlc)
49
private ArrayList subMenus = new ArrayList();
50
//what module that should receive all remotebutton changes
51
private String curButtonReceiver;
52
//what module that is visible on all flashclients
53
//often same as curButtonReceiver, but not when curButtonReceiver is vlc-module 
54
private String curSubMenu;
55
 
56
private String currentAddress = "";
57
private int currentLevel = 0;
58
 
59
private ArrayList userLogin = new ArrayList();
60
private ArrayList clientsConnected = new ArrayList();
61
 
62
//holds track of what item is marked in the root_menu (menu system)
63
private String rootMenuMiddleId;
64
 
65
private boolean guestCanView;
66
 
67
String padUp;
68
String padDown;
69
String padLeft;
70
String padRight;
71
String padOk;
72
 
73
 
74
    /**
75
     * Creates a new instance of .
76
     */
77
    public modMenuSystem() {
78
        //construct MbModule
79
        super();
80
        //initial values
81
 
82
        addDependency("RemoteControl");
83
 
84
        //from start the root-menu should be visible
85
        curButtonReceiver = name();
86
        curSubMenu = name();
87
        rootMenuMiddleId = "0";
88
 
89
        //subMenuLastMenu = "";
90
        //register our packet data handler
91
        setPacketDataHandler(new PacketDataHandler());
92
        //packetXMLParser = new XMLParser(new PacketDataHandler());
93
        flinshDataHandler = new FlinshDataHandler();
94
   }
95
 
96
    public String name() {
97
        return "MenuSystem";
98
    }
99
 
100
    public String description() {
101
        return "bla";
102
    }
103
 
104
    /**
105
     * This method sets default values on all _required_ data
106
     * fields in the data repository.
107
     */
108
    public void initDataFields() {
109
        //set default values on all REQUIRED option fields before starting up subsystems
110
        //options.putField("mode", "simple");
111
        //options.putField("checkinterval", "5");
112
        //options.putField("displaytext", "New mail");
113
//        options.putField("port", "2050");
114
    }
115
 
116
    public void handleServerData(String data, String address) {
117
 
118
        //nulltecken finns, tar bort
119
        data = data.replaceAll("" + EOF, "");
120
 
121
        if (data.length() > 0) {
122
            if (data.equals("<ping />")) {
123
                //gör inget om det är ping
124
            } else {
125
                //_debug.println("got data: " + data);
126
 
127
                //kan vara en säkerhetsrisk att skicka med det såhär, klienten kan ju
128
                //konstruera en sån här sträng och skicka till oss
129
                //data = "<clientaddress value=\"" + address + "\">" + data;
130
                //fet säkerhetsrisk ja
131
                //private String currentAddress = "";
132
                currentLevel = 0;
133
                //check user level
134
                currentAddress = address;
135
                for (int i=0; i<clientsConnected.size(); i++) {
136
                    String adr = ((ClientObj)clientsConnected.get(i)).address;
137
                    if (adr.equals(address)) {
138
                        currentLevel = ((ClientObj)clientsConnected.get(i)).level;
139
                        break;
140
                    }
141
                }
142
 
143
 
144
                //<flinshpacket id="MainMenu" middleitem="1" />
145
                if (flinshDataHandler!=null) {
146
                    //create XML parser and try to parse configuration file
147
                    XMLParser xmlParser = new XMLParser(flinshDataHandler);
148
                    try {
149
                        xmlParser.parseString(data);
150
                    } catch (SAXException e) {
151
                        _errors.println("The data send from flinsh contains errors:");
152
                        _errors.println(e);
153
                        e.printStackTrace();
154
                    } catch (IOException e) {
155
                        //I/O-exception. that's worse, so lets warn
156
                        _errors.println("I/O-error while trying to read data from flinsh:");
157
                        _errors.println(e);
158
                        e.printStackTrace();
159
                    }
160
                }
161
                //allt parsas nu av xml-parsern
162
            }
163
        }
164
 
165
 
166
    }
167
 
168
    /**
169
     * When a client dropps out, delete it from the client list
170
     *
171
     */
172
    public void clientDropped(String address) {
173
        for (int i=0; i<clientsConnected.size(); i++) {
174
            String adr = ((ClientObj)clientsConnected.get(i)).address;
175
            if (adr.equals(address)) {
176
                clientsConnected.remove(i);
177
                _debug.println("client dropped: " + address);
178
                break;
179
 
180
            }
181
        }
182
    }
183
 
184
    /**
185
     * When flins client connects it should get the latest menu. If its the root menu  
186
     * sendRootMenu get called. If its a submenu a refresh is sent to that submenu
187
     * and the submenu should send out the latest menu to menusystem.
188
     */
189
    public void setRemoteAddress(String address) {
190
        //_debug.println("got connection: " + address);
191
 
192
        /*
193
         * check if the newly connected client has a level specified in config
194
         */
195
        int level = 0;
196
        _debug.println("client connected: " + address);
197
        //rota igenom listan över de möjliga logins som finns
198
        for (int i=0; i<userLogin.size(); i++) {
199
            if (((UserLoginObj)userLogin.get(i)).user.equals("ip")) {
200
                String userLoginIp = ((UserLoginObj)userLogin.get(i)).password;
201
                String[] ipPort = address.split(":");
202
 
203
                if (ipPort[0].equals("/" + userLoginIp)) {
204
                    if (((UserLoginObj)userLogin.get(i)).level > level) {
205
                        level = ((UserLoginObj)userLogin.get(i)).level;
206
                        _debug.println("client got level by ip: " + level);
207
                    }
208
                }
209
            }
210
        }
211
        //lägg till klienten i listan över klienter:
212
        clientsConnected.add(new ClientObj(address, level));
213
 
214
        if (curSubMenu.equals(name())) {
215
            sendRootMenu(address);
216
        } else {
217
            sendMacbeth(curSubMenu, "<refresh />");
218
        }
219
    }
220
 
221
 
222
    /**
223
     *
224
     * @param address Specifies flinsh-client to send data to, send to all clients if null
225
     */
226
    private void sendRootMenu(String address) {
227
        //nu ska vi visa rootmenyn (lista alla submodulers displayname)
228
        String dataToSend = "<?xml version=\"1.0\"?><packet menuid=\"MainMenu\"><data>";
229
 
230
        dataToSend = dataToSend + "<middleid>" + rootMenuMiddleId + "</middleid><list id=\"menudata\">";
231
        for (int i = 0; i < subMenus.size(); i++) {
232
            //generera e
233
            dataToSend = dataToSend + "<item id=\"" + i + "\" title=\"" + ((SubMenu)subMenus.get(i)).getDisplayName() + "\" desc=\"" + ((SubMenu)subMenus.get(i)).getDisplayDesc() + "\" />";
234
            /*
235
            dataToSend = dataToSend + "<item>";
236
            dataToSend = dataToSend + "<id>" + i + "</id>";
237
            dataToSend = dataToSend + "<title>" + ((SubMenu)subMenus.get(i)).getDisplayName() + "</title>";
238
            dataToSend = dataToSend + "<description>" + ((SubMenu)subMenus.get(i)).getDisplayDesc() + "</description>";
239
            dataToSend = dataToSend + "</item>";
240
            */
241
        }
242
        dataToSend = dataToSend + "</list></data></packet>" + EOF;
243
 
244
        if (address != null) {
245
            //skicka till en klient
246
            if (guestCanView) {
247
                flinshServer.sendToClient(dataToSend, address);
248
            } else {
249
                //skicka till alla inloggade med adressen address (level > 0)
250
                for (int i=0; i<clientsConnected.size(); i++) {
251
                    String adr = ((ClientObj)clientsConnected.get(i)).address;
252
                    int level = ((ClientObj)clientsConnected.get(i)).level;
253
                    if (adr.equals(address) && level > 0) {
254
                        flinshServer.sendToClient(dataToSend, adr);
255
                    }
256
                }
257
            }
258
 
259
        } else {
260
            //skicka till alla
261
            if (guestCanView) {
262
                flinshServer.sendToAll(dataToSend);
263
            } else {
264
                //skicka till alla inloggade (level > 0)
265
                for (int i=0; i<clientsConnected.size(); i++) {
266
                    String adr = ((ClientObj)clientsConnected.get(i)).address;
267
                    int level = ((ClientObj)clientsConnected.get(i)).level;
268
                    if (level > 0) {
269
                        flinshServer.sendToClient(dataToSend, adr);
270
                    }
271
                }
272
            }
273
        }
274
    }
275
 
276
    private void sendData(String address, String data) {
277
        String dataToSend = "<?xml version=\"1.0\"?>";
278
        dataToSend = dataToSend + data;    
279
        dataToSend = dataToSend + EOF;
280
        if (address != null) {
281
            //skicka till en klient
282
            flinshServer.sendToClient(dataToSend, address);
283
        } else {
284
            //skicka till alla
285
            if (guestCanView) {
286
                flinshServer.sendToAll(dataToSend);
287
            } else {
288
                //skicka till alla inloggade (level > 0)
289
                for (int i=0; i<clientsConnected.size(); i++) {
290
                    String adr = ((ClientObj)clientsConnected.get(i)).address;
291
                    int level = ((ClientObj)clientsConnected.get(i)).level;
292
                    if (level > 0) {
293
                        flinshServer.sendToClient(dataToSend, adr);
294
                    }
295
                }
296
            }
297
        }      
298
    }
299
 
300
    private void sendCommand(String address, String command) {
301
        String dataToSend = "<?xml version=\"1.0\"?><packet menuid=\"MainMenu\"><command>";
302
        dataToSend = dataToSend + command;
303
        dataToSend = dataToSend + "</command></packet>" + EOF;
304
        //_debug.println("skickar " + dataToSend);
305
        if (address != null) {
306
            //skicka till en klient
307
            flinshServer.sendToClient(dataToSend, address);
308
        } else {
309
            //skicka till alla
310
            if (guestCanView) {
311
                flinshServer.sendToAll(dataToSend);
312
            } else {
313
                //skicka till alla inloggade (level > 0)
314
                for (int i=0; i<clientsConnected.size(); i++) {
315
                    String adr = ((ClientObj)clientsConnected.get(i)).address;
316
                    int level = ((ClientObj)clientsConnected.get(i)).level;
317
                    if (level > 0) {
318
                        flinshServer.sendToClient(dataToSend, adr);
319
                    }
320
                }
321
            }
322
        }
323
    }
324
 
325
    public void startup() throws MbStartupException {
326
        //startup MbModule
327
        super.startup();
328
 
329
        //get all login users/ip objects from the data repository
330
        DataRepository.DataList list = dataRepository.getList("login");
331
        if (list!=null) {
332
            Iterator it = list.items();
333
            while (it.hasNext()) {
334
                DataRepository.DataListItem item = (DataRepository.DataListItem)it.next();
335
                String name = (String)item.getField("user");
336
                String passIp = (String)item.getField("pass");
337
                int level = 0;
338
                try {
339
                    level = Integer.parseInt((String)item.getField("level"));
340
                } catch (NumberFormatException ex) {
341
                    _errors.println("Config error: level not a number: " + (String)item.getField("level"));
342
                }
343
 
344
                userLogin.add(new UserLoginObj(name, passIp, level));
345
            }
346
        }
347
 
348
        guestCanView = ((String)options.getField("guestcanview")).equals("true");
349
 
350
        int flinshServerPort = Integer.parseInt(options.getField("port"));
351
        //konfigurerbar port via vanlig config
352
        if (flinshServerPort >= 1024) {
353
            flinshServer = new TcpServer(flinshServerPort, this);
354
            flinshServer.startServer();
355
            flinshServer.setTcpNoDelay(true);
356
        } else {
357
            _errors.println("Config error: Port number must be greater than or equal to 1024");
358
        }
359
 
360
        padUp = options.getField("padup");
361
        padDown = options.getField("paddown");
362
        padLeft = options.getField("padleft");
363
        padRight = options.getField("padright");
364
        padOk = options.getField("padok");
365
        //lets send requests for their remote control buttons
366
        MbPacket p = new MbPacket();
367
        p.setDestination(new MbLocation("self", "RemoteControl"));
368
        p.appendContents("  <buttonrequest button=\"" + padUp + "\" module=\"" + name() + "\" />");
369
        p.appendContents("  <buttonrequest button=\"" + padDown + "\" module=\"" + name() + "\" />");
370
        p.appendContents("  <buttonrequest button=\"" + padLeft + "\" module=\"" + name() + "\" />");
371
        p.appendContents("  <buttonrequest button=\"" + padRight + "\" module=\"" + name() + "\" />");
372
        p.appendContents("  <buttonrequest button=\"" + padOk + "\" module=\"" + name() + "\" />");
373
 
374
        sendPacket(p);
375
 
376
    }
377
 
378
    /**
379
     * Shuts down this module.
380
     */
381
    public void shutdown() {
382
        //stop timer if it's running
383
        /*if (requestDataTimer!=null) {
384
            if (requestDataTimer.isRunning()) {
385
                requestDataTimer.stop();
386
            }
387
        }*/
388
        //shut down MbModule
389
        flinshServer.stopServer();
390
        super.shutdown();
391
    }
392
 
393
    private void sendMacbeth(String receiver, String data) {
394
        MbPacket p = new MbPacket();
395
        p.setDestination(new MbLocation("self", receiver));
396
        p.appendContents(data);
397
        sendPacket(p);                 
398
 
399
    }
400
 
401
    private void parseKeys(String button, String state, int level) {
402
        //_debug.println("knapp " + button + " i state " + state);
403
        if (state.equals("DOWN")) {
404
            if (padUp.equals(button)) {
405
                //if current button-receiver is the menu system module
406
                if (curButtonReceiver.equals(name())) {
407
                    if (level >= 1) {
408
                        sendCommand(null, "<scroll>1</scroll>");
409
                    }
410
                } else {
411
                    sendMacbeth(curButtonReceiver, "<padUp state=\"DOWN\" level=\"" + level + "\" />");
412
                }
413
            }
414
            else if (padDown.equals(button)) {
415
                //if current button-receiver is the menu system module
416
                if (curButtonReceiver.equals(name())) {
417
                    if (level >= 1) {
418
                        sendCommand(null, "<scroll>-1</scroll>");
419
                    }
420
                } else {
421
                    sendMacbeth(curButtonReceiver, "<padDown state=\"DOWN\" level=\"" + level + "\" />");
422
                }
423
            }
424
            else if (padRight.equals(button)) {
425
                //if current button-receiver is the menu system module
426
                if (curButtonReceiver.equals(name())) {
427
                    if (level >= 2) {  
428
                        curButtonReceiver = ((SubMenu)subMenus.get(Integer.parseInt(rootMenuMiddleId))).getModuleName();
429
                        curSubMenu = curButtonReceiver;
430
                        sendMacbeth(curSubMenu, "<activate />");
431
                    }
432
                } else {
433
                    sendMacbeth(curButtonReceiver, "<padRight state=\"DOWN\" level=\"" + level + "\" />");
434
                }
435
            } else if (padLeft.equals(button)) {
436
                //if current button-receiver is the menu system module
437
                if (curButtonReceiver.equals(name())) {
438
                    //do nothing
439
                } else {
440
                    sendMacbeth(curButtonReceiver, "<padLeft state=\"DOWN\" level=\"" + level + "\" />");
441
                }
442
            }
443
 
444
            else if (padOk.equals(button)) {
445
                //if current button-receiver is the menu system module
446
                if (curButtonReceiver.equals(name())) {
447
 
448
                } else {
449
                    sendMacbeth(curButtonReceiver, "<padOk state=\"DOWN\" level=\"" + level + "\" />");
450
                }
451
            }
452
        }
453
        else if (state.equals("UP")) {
454
            if (padUp.equals(button)) {
455
                //if current button-receiver is the menu system module
456
                if (curButtonReceiver.equals(name())) {
457
                    if (level >= 1) {
458
                        sendCommand(null, "<scroll>0</scroll>");
459
                    }
460
                } else {
461
                    sendMacbeth(curButtonReceiver, "<padUp state=\"UP\" level=\"" + level + "\" />");
462
                }
463
            }
464
            else if (padDown.equals(button)) {
465
                //if current button-receiver is the menu system module
466
                if (curButtonReceiver.equals(name())) {
467
                    if (level >= 1) {
468
                        sendCommand(null, "<scroll>0</scroll>");
469
                    }
470
                } else {
471
                    sendMacbeth(curButtonReceiver, "<padDown state=\"UP\" level=\"" + level + "\" />");
472
                }
473
            }
474
            else if (padOk.equals(button)) {
475
                //if current button-receiver is the menu system module
476
                if (curButtonReceiver.equals(name())) {
477
 
478
                } else {
479
                    sendMacbeth(curButtonReceiver, "<padOk state=\"UP\" level=\"" + level + "\" />");
480
                }
481
            }
482
            else if (padLeft.equals(button)) {
483
                //if current button-receiver is the menu system module
484
                if (curButtonReceiver.equals(name())) {
485
 
486
                } else {
487
                    sendMacbeth(curButtonReceiver, "<padLeft state=\"UP\" level=\"" + level + "\" />");
488
                }
489
            }
490
            else if (padRight.equals(button)) {
491
                //if current button-receiver is the menu system module
492
                if (curButtonReceiver.equals(name())) {
493
 
494
                } else {
495
                    sendMacbeth(curButtonReceiver, "<padRight state=\"UP\" level=\"" + level + "\" />");
496
                }
497
            }
498
 
499
        }
500
    }
501
 
502
 
503
    /**
504
     * Takes care of XML-data found in incoming macbeth-packets.
505
     */
506
    private class PacketDataHandler implements XMLDataHandler {
507
        public void XMLstartElement(String element, HashMap attributes) {
508
            if (element.equals("packet")) {
509
                if (currentPacket.getSource().getModule().equals(curSubMenu)) {
510
                    //data arrive from active submenu
511
                    sendData(null, currentPacket.getContents());
512
 
513
                } else {
514
                    //data arrives from submenu that is not active
515
                    //what happens then?
516
                }
517
 
518
            } else if (element.equals("deactivates") ) {
519
                String module = currentPacket.getSource().getModule();
520
                if (curSubMenu.equals(module)) {
521
                    curSubMenu = name();
522
                    sendRootMenu(null);
523
                    sendMacbeth(curSubMenu, "<deactivate />");
524
                }
525
                if (curButtonReceiver.equals(module)) {
526
                    curButtonReceiver = name();
527
                    sendMacbeth(curButtonReceiver, "<deactivate />");
528
                }
529
 
530
            } else if (element.equals("request") ) {
531
                //om en undermeny vill ha uppmärksamhet skickar den "request"
532
                //vad är kraven på att en undermeny ska få visas på begäran?
533
                //en timeout när vald meny inte skickat något?
534
                //eller att en krävd visning kan klickas bort med cancel/back på fjärren
535
                // och att man då återgår till den meny som visades innan
536
 
537
                String module = currentPacket.getSource().getModule();
538
                if (!curSubMenu.equals(module)) {
539
                    //kontroller här?
540
                    curSubMenu = module;
541
                    sendMacbeth(curSubMenu, "<activate />");
542
                }                        
543
                if (!curButtonReceiver.equals(module)) {
544
                    //kontroller här?
545
                    curButtonReceiver = module;
546
                }
547
 
548
            /*
549
             * a submenu should be able to register itself to the menu system
550
             * it provides a name and description to display, but also a true/false value
551
             * indicating if the submenu should be displayed in the root_menu list at all
552
             */
553
            } else if (element.equals("registersubmod") && attributes.containsKey("displayname") && attributes.containsKey("visible") && attributes.containsKey("displaydesc")) {
554
                String displayname = (String)attributes.get("displayname");
555
                String displaydesc = (String)attributes.get("displaydesc");
556
                _debug.println(displayname + " registrerar sig");
557
                //_debug.println(displaydesc);
558
                String module = currentPacket.getSource().getModule();
559
                boolean visible = false;
560
                if (attributes.get("visible").toString().equals("true")) {
561
                    visible = true;
562
                }
563
 
564
                //has this module been reged before?
565
                boolean exists = false;
566
                for (int i = 0; i < subMenus.size(); i++) {
567
                    if (((SubMenu)subMenus.get(i)).getModuleName().equals(module)) {
568
                        exists = true;
569
                        break;
570
                    }
571
                }
572
                if (!exists) {
573
                    //so create a new submenu object
574
                    SubMenu sm = new SubMenu(module, displayname, displaydesc, visible);
575
                    subMenus.add(sm);
576
                    //refresh flinsh-client menu (if it is root menu)
577
                    if (curSubMenu.equals(name())) {
578
                        sendRootMenu(null);
579
                    }                        
580
                }
581
 
582
            //en submeny ska kunna avregistrera sig också, om den avslutas
583
            } else if (element.equals("unregistersubmod") ) {
584
                String module = currentPacket.getSource().getModule();
585
 
586
                //has this module been registered?
587
                for (int i = 0; i < subMenus.size(); i++) {
588
                    if (((SubMenu)subMenus.get(i)).getModuleName().equals(module)) {
589
                        subMenus.remove(i);
590
 
591
//                      TODO: avskaffa parseint på data som kommer utifrån
592
                        if (Integer.parseInt(rootMenuMiddleId) >= subMenus.size() & Integer.parseInt(rootMenuMiddleId) > 0) {
593
                            rootMenuMiddleId = "" + (Integer.parseInt(rootMenuMiddleId) - 1);
594
                        }
595
 
596
                        if (curSubMenu.equals(module)) {
597
                            curSubMenu = name();
598
                            //refresha klientens meny (om den är root)
599
                            sendRootMenu(null);
600
                        }                        
601
                        if (curButtonReceiver.equals(module)) {
602
                            curButtonReceiver = name();
603
                        }                        
604
 
605
                        break;
606
                    }
607
                }
608
            }
609
 
610
            /* Ex: <remotecontrol button="NUMERIC4" state="DOWN" />
611
             * This is a notification from the remote control module
612
             * about one of our requested remote control buttons have
613
             * been pressed. */
614
            else if (element.equals("remotecontrol") && attributes.containsKey("button") && attributes.containsKey("state")) {
615
                String state = (String)attributes.get("state");
616
                String button = (String)attributes.get("button");
617
                parseKeys(button, state, 3);
618
            }
619
 
620
        }
621
        public void XMLendElement(String element) {}
622
        public void XMLelementData(String data) {}
623
        public void XMLdocumentStart() {}
624
        public void XMLdocumentEnd() {}
625
    }
626
 
627
    /**
628
     * Takes care of XML-data found in incoming flinsh-packets.
629
     */
630
    private class FlinshDataHandler implements XMLDataHandler {
631
        public void XMLstartElement(String element, HashMap attributes) {
632
            if (element.equals("flinshpacket") && attributes.containsKey("button") && attributes.containsKey("state")) {
633
                String button = (String)attributes.get("button");
634
                String state = (String)attributes.get("state");
635
                String newButton = "";
636
 
637
                if (button.equals("padUp")) {
638
                    newButton = padUp;
639
                } else if (button.equals("padDown")) {
640
                    newButton = padDown;
641
                } else if (button.equals("padLeft")) {
642
                    newButton = padLeft;
643
                } else if (button.equals("padRight")) {
644
                    newButton = padRight;
645
                } else if (button.equals("padOk")) {
646
                    newButton = padOk;
647
                }
648
 
649
                if (!newButton.equals("") && (state.equals("UP") || state.equals("DOWN"))) {
650
                    parseKeys(newButton, state, currentLevel);
651
                }
652
            }
653
            else if (element.equals("flinshpacket") && attributes.containsKey("menuid") && attributes.containsKey("middleid")) {
654
                String id = (String)attributes.get("middleid");
655
                String menuid = (String)attributes.get("menuid");
656
                //int flinshMiddleItem = Integer.parseInt(id);
657
 
658
                //om root:
659
                if (curButtonReceiver.equals(name())) {
660
                    if (currentLevel >= 2) {
661
                        rootMenuMiddleId = id;
662
                    }
663
                } else {
664
                    sendMacbeth(curSubMenu, "<middleid value=\"" + id + "\" menuid=\"" + menuid + "\" userlevel=\"" + currentLevel + "\" />");
665
                }
666
                //_debug.println("data parsad, id: " + menuid + " middleitem: " + id);
667
            }
668
            else if (element.equals("flinshpacket") && attributes.containsKey("login") && attributes.containsKey("pass")) {
669
                String user = (String)attributes.get("login");
670
                String pass = (String)attributes.get("pass");
671
                login(currentAddress, user, pass);
672
 
673
            }
674
 
675
        }
676
        public void XMLendElement(String element) {}
677
        public void XMLelementData(String data) {}
678
        public void XMLdocumentStart() {}
679
        public void XMLdocumentEnd() {}
680
    }
681
 
682
    /**
683
     *
684
     * @param address
685
     * @param user
686
     * @param pass
687
     */
688
    private void login(String address, String user, String pass) {
689
        //ip är inte ett giltigt användarnamn
690
        //eftersom ip används för att få autologin för ipadresser
691
        if (!user.equals("ip")) {
692
            int level = 0;
693
            //rota igenom listan över de möjliga logins som finns
694
            for (int i=0; i<userLogin.size(); i++) {
695
                String username = ((UserLoginObj)userLogin.get(i)).user;
696
                String userLoginIp = ((UserLoginObj)userLogin.get(i)).password;
697
                if (username.equals(user) && userLoginIp.equals(pass)) {
698
                    level = ((UserLoginObj)userLogin.get(i)).level;
699
                    //rota igenom alla inloggade klienter
700
                    for (int j=0; j<clientsConnected.size(); j++) {
701
                        String adr = ((ClientObj)clientsConnected.get(j)).address;
702
                        if (adr.equals(address)) {
703
                            int oldlevel = ((ClientObj)clientsConnected.get(j)).level;
704
                            if (oldlevel < level) {
705
                                _debug.println("client logged in with new level: " + level);
706
                                ((ClientObj)clientsConnected.get(j)).level = level;
707
                                if (oldlevel == 0 && !guestCanView) {
708
                                    //skicka meny till klienten
709
                                    if (curSubMenu.equals(name())) {
710
                                        sendRootMenu(address);
711
                                    } else {
712
                                        sendMacbeth(curSubMenu, "<refresh />");
713
                                    }
714
                                }
715
                            }
716
                            break;
717
                        }
718
                    }
719
                    break;
720
                }
721
            }  
722
        }
723
    }
724
    /*private class TimerListener implements ActionListener {
725
 
726
           public void actionPerformed(ActionEvent e) {
727
               _debug.println("timer ping");
728
               //först skicka testdata här bara
729
               //börja med <scrollup />
730
               testserver.sendToAll("<?xml version=\"1.0\"?><contentdata><middleitem>0</middleitem><contentname>MainMenu</contentname><list><item><title>08:00 Clifford, den lilla r&#246;da valpen</title><description>Tecknad serie. Del 13 av 17.</description></item><item><title>08:35 Lantmusen och stadsmusen</title><description>Animerad serie. M&#246;ssen Alexander och Emily reser jorden runt. Del 9 av 13.</description></item><item><title>15:00 Perkele</title><description>Test bla bla</description></item></list></contentdata>" + EOF);
731
 
732
               //koppla upp sig mot http://www.arune.se/tv/tv_rss_now.php?id0=21&id1=22&id2=26&id3=27&id4=10&id5=42&id6=14&id7=89
733
               //forma om den xml till det format flinsh vill ha skiten
734
               //skicka till flinsh
735
           }
736
        }*/
737
 
738
    /**
739
     * Objekt som håller reda på vilka möjliga inloggningar klienten kan göra
740
     */
741
    private class UserLoginObj {
742
        public String user;
743
        public String password;
744
        public int level;
745
        /**
746
         * Creates a new instance of UserLoginObj.
747
         */
748
        public UserLoginObj(String user, String password, int level) {
749
            this.user = user;
750
            this.password = password;
751
            this.level = level;
752
        }
753
    }
754
 
755
    /**
756
     * Objekt som håller reda på alla inloggade klienter
757
     * @author arune
758
     */
759
    private class ClientObj {
760
        public String address;
761
        public int level;
762
        /**
763
         * Creates a new instance of ClientObj.
764
         */
765
        public ClientObj(String address, int level) {
766
            this.address = address;
767
            this.level = level;
768
        }
769
    }
770
}