Minor changes from code inspection results
[zxing.git] / android / src / com / google / zxing / client / android / result / AddressBookResultHandler.java
1 /*
2  * Copyright (C) 2008 ZXing authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.google.zxing.client.android.result;
18
19 import com.google.zxing.client.android.R;
20 import com.google.zxing.client.result.AddressBookParsedResult;
21 import com.google.zxing.client.result.ParsedResult;
22
23 import android.app.Activity;
24 import android.telephony.PhoneNumberUtils;
25 import android.text.Spannable;
26 import android.text.SpannableString;
27 import android.text.style.StyleSpan;
28
29 import java.text.DateFormat;
30 import java.text.ParsePosition;
31 import java.text.SimpleDateFormat;
32 import java.util.Date;
33
34 /**
35  * Handles address book entries.
36  *
37  * @author dswitkin@google.com (Daniel Switkin)
38  */
39 public final class AddressBookResultHandler extends ResultHandler {
40
41   private static final DateFormat[] DATE_FORMATS = {
42     new SimpleDateFormat("yyyyMMdd"),
43     new SimpleDateFormat("yyyyMMdd'T'HHmmss"),
44     new SimpleDateFormat("yyyy-MM-dd"),
45     new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"),
46   };
47
48   private final boolean[] fields;
49   private int buttonCount;
50
51   // This takes all the work out of figuring out which buttons/actions should be in which
52   // positions, based on which fields are present in this barcode.
53   private int mapIndexToAction(int index) {
54     if (index < buttonCount) {
55       int count = -1;
56       for (int x = 0; x < MAX_BUTTON_COUNT; x++) {
57         if (fields[x]) {
58           count++;
59         }
60         if (count == index) {
61           return x;
62         }
63       }
64     }
65     return -1;
66   }
67
68   public AddressBookResultHandler(Activity activity, ParsedResult result) {
69     super(activity, result);
70     AddressBookParsedResult addressResult = (AddressBookParsedResult) result;
71     String[] addresses = addressResult.getAddresses();
72     boolean hasAddress = addresses != null && addresses.length > 0 && addresses[0].length() > 0;
73     String[] phoneNumbers = addressResult.getPhoneNumbers();
74     boolean hasPhoneNumber = phoneNumbers != null && phoneNumbers.length > 0;
75     String[] emails = addressResult.getEmails();
76     boolean hasEmailAddress = emails != null && emails.length > 0;
77
78     fields = new boolean[MAX_BUTTON_COUNT];
79     fields[0] = true; // Add contact is always available
80     fields[1] = hasAddress;
81     fields[2] = hasPhoneNumber;
82     fields[3] = hasEmailAddress;
83
84     buttonCount = 0;
85     for (int x = 0; x < MAX_BUTTON_COUNT; x++) {
86       if (fields[x]) {
87         buttonCount++;
88       }
89     }
90   }
91
92   @Override
93   public int getButtonCount() {
94     return buttonCount;
95   }
96
97   @Override
98   public int getButtonText(int index) {
99     int action = mapIndexToAction(index);
100     switch (action) {
101       case 0:
102         return R.string.button_add_contact;
103       case 1:
104         return R.string.button_show_map;
105       case 2:
106         return R.string.button_dial;
107       case 3:
108         return R.string.button_email;
109       default:
110         throw new ArrayIndexOutOfBoundsException();
111     }
112   }
113
114   @Override
115   public void handleButtonPress(int index) {
116     AddressBookParsedResult addressResult = (AddressBookParsedResult) getResult();
117     String[] addresses = addressResult.getAddresses();
118     String address1 = addresses == null || addresses.length < 1 ? null : addresses[0];
119     int action = mapIndexToAction(index);
120     switch (action) {
121       case 0:
122         addContact(addressResult.getNames(), addressResult.getPhoneNumbers(),
123             addressResult.getEmails(), addressResult.getNote(),
124             address1, addressResult.getOrg(),
125             addressResult.getTitle());
126         break;
127       case 1:
128         String[] names = addressResult.getNames();
129         String title = names != null ? names[0] : null;
130         searchMap(address1, title);
131         break;
132       case 2:
133         dialPhone(addressResult.getPhoneNumbers()[0]);
134         break;
135       case 3:
136         sendEmail(addressResult.getEmails()[0], null, null);
137         break;
138       default:
139         break;
140     }
141   }
142
143   private static Date parseDate(String s) {
144     for (DateFormat currentFomat : DATE_FORMATS) {
145       synchronized (currentFomat) {
146         currentFomat.setLenient(false);
147         Date result = currentFomat.parse(s, new ParsePosition(0));
148         if (result != null) {
149           return result;
150         }
151       }
152     }
153     return null;
154   }
155
156   // Overriden so we can hyphenate phone numbers, format birthdays, and bold the name.
157   @Override
158   public CharSequence getDisplayContents() {
159     AddressBookParsedResult result = (AddressBookParsedResult) getResult();
160     StringBuffer contents = new StringBuffer(100);
161     ParsedResult.maybeAppend(result.getNames(), contents);
162     int namesLength = contents.length();
163
164     String pronunciation = result.getPronunciation();
165     if (pronunciation != null && pronunciation.length() > 0) {
166       contents.append("\n(");
167       contents.append(pronunciation);
168       contents.append(')');
169     }
170
171     ParsedResult.maybeAppend(result.getTitle(), contents);
172     ParsedResult.maybeAppend(result.getOrg(), contents);
173     ParsedResult.maybeAppend(result.getAddresses(), contents);
174     String[] numbers = result.getPhoneNumbers();
175     if (numbers != null) {
176       for (String number : numbers) {
177         ParsedResult.maybeAppend(PhoneNumberUtils.formatNumber(number), contents);
178       }
179     }
180     ParsedResult.maybeAppend(result.getEmails(), contents);
181     ParsedResult.maybeAppend(result.getURL(), contents);
182
183     String birthday = result.getBirthday();
184     if (birthday != null && birthday.length() > 0) {
185       Date date = parseDate(birthday);
186       if (date != null) {
187         ParsedResult.maybeAppend(DateFormat.getDateInstance().format(date.getTime()), contents);
188       }
189     }
190     ParsedResult.maybeAppend(result.getNote(), contents);
191
192     if (namesLength > 0) {
193       // Bold the full name to make it stand out a bit.
194       Spannable styled = new SpannableString(contents.toString());
195       styled.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, namesLength, 0);
196       return styled;
197     } else {
198       return contents.toString();
199     }
200   }
201
202   @Override
203   public int getDisplayTitle() {
204     return R.string.result_address_book;
205   }
206 }