altosuilib: Wait for product data while scanning
[fw/altos] / altosuilib / AltosUIMapImage.java
1 /*
2  * Copyright © 2010 Anthony Towns <aj@erisian.com.au>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 package org.altusmetrum.altosuilib_3;
19
20 import javax.swing.*;
21 import javax.imageio.ImageIO;
22 import java.awt.image.*;
23 import java.awt.*;
24 import java.io.*;
25 import java.net.*;
26
27 public class AltosUIMapImage implements AltosUIMapStoreListener {
28         static final long google_maps_ratelimit_ms = 1200;
29         // Google limits static map queries to 50 per minute per IP, so
30         // each query should take at least 1.2 seconds.
31
32         static final int        success = 0;
33         static final int        loading = 1;
34         static final int        failed = 2;
35         static final int        bad_request = 3;
36         static final int        forbidden = 4;
37
38         static long             forbidden_time;
39         static boolean          forbidden_set = false;
40         static final long       forbidden_interval = 60l * 1000l * 1000l * 1000l;
41
42         AltosUIMapTile          tile;           /* Notify when image has been loaded */
43         Image                   image;
44         AltosUIMapStore         store;
45         long                    used;
46
47         class loader implements Runnable {
48                 public void run() {
49                         if (image != null)
50                                 tile.notify_image(image);
51                         try {
52                                 image = ImageIO.read(store.file);
53                         } catch (Exception ex) {
54                         }
55                         if (image == null)
56                                 tile.set_status(failed);
57                         else
58                                 tile.set_status(success);
59                         tile.notify_image(image);
60                 }
61         }
62
63         private void load() {
64                 loader  l = new loader();
65                 Thread  lt = new Thread(l);
66                 lt.start();
67         }
68
69         public void flush() {
70                 if (image != null) {
71                         image.flush();
72                         image = null;
73                 }
74         }
75
76         public boolean has_map() {
77                 return store.status() == AltosUIMapStore.success;
78         }
79
80         public synchronized void notify_store(AltosUIMapStore store, int status) {
81                 switch (status) {
82                 case AltosUIMapStore.loading:
83                         break;
84                 case AltosUIMapStore.success:
85                         load();
86                         break;
87                 default:
88                         tile.set_status(status);
89                         tile.notify_image(null);
90                 }
91         }
92
93         public AltosUIMapImage(AltosUIMapTile tile, AltosUIMapStore store) throws IOException {
94                 this.tile = tile;
95                 this.image = null;
96                 this.store = store;
97                 this.used = 0;
98
99                 int status = store.status();
100                 switch (status) {
101                 case AltosUIMapStore.loading:
102                         store.add_listener(this);
103                         break;
104                 case AltosUIMapStore.success:
105                         load();
106                         break;
107                 default:
108                         tile.set_status(status);
109                         tile.notify_image(null);
110                         break;
111                 }
112         }
113 }