Lots of updates:
[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   private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");
41
42   private final boolean[] fields;
43   private int buttonCount;
44
45   // This takes all the work out of figuring out which buttons/actions should be in which
46   // positions, based on which fields are present in this barcode.
47   private int mapIndexToAction(int index) {
48     if (index < buttonCount) {
49       int count = -1;
50       for (int x = 0; x < MAX_BUTTON_COUNT; x++) {
51         if (fields[x]) {
52           count++;
53         }
54         if (count == index) {
55           return x;
56         }
57       }
58     }
59     return -1;
60   }
61
62   public AddressBookResultHandler(Activity activity, ParsedResult result) {
63     super(activity, result);
64     AddressBookParsedResult addressResult = (AddressBookParsedResult) result;
65     String address = addressResult.getAddress();
66     boolean hasAddress = address != null && address.length() > 0;
67     String[] phoneNumbers = addressResult.getPhoneNumbers();
68     boolean hasPhoneNumber = phoneNumbers != null && phoneNumbers.length > 0;
69     String[] emails = addressResult.getEmails();
70     boolean hasEmailAddress = emails != null && emails.length > 0;
71
72     fields = new boolean[MAX_BUTTON_COUNT];
73     fields[0] = true; // Add contact is always available
74     fields[1] = hasAddress;
75     fields[2] = hasPhoneNumber;
76     fields[3] = hasEmailAddress;
77
78     buttonCount = 0;
79     for (int x = 0; x < MAX_BUTTON_COUNT; x++) {
80       if (fields[x]) {
81         buttonCount++;
82       }
83     }
84   }
85
86   @Override
87   public int getButtonCount() {
88     return buttonCount;
89   }
90
91   @Override
92   public int getButtonText(int index) {
93     int action = mapIndexToAction(index);
94     switch (action) {
95       case 0:
96         return R.string.button_add_contact;
97       case 1:
98         return R.string.button_show_map;
99       case 2:
100         return R.string.button_dial;
101       case 3:
102         return R.string.button_email;
103       default:
104         throw new ArrayIndexOutOfBoundsException();
105     }
106   }
107
108   @Override
109   public void handleButtonPress(int index) {
110     AddressBookParsedResult addressResult = (AddressBookParsedResult) result;
111     int action = mapIndexToAction(index);
112     switch (action) {
113       case 0:
114         addContact(addressResult.getNames(), addressResult.getPhoneNumbers(),
115             addressResult.getEmails(), addressResult.getNote(),
116             addressResult.getAddress(), addressResult.getOrg(),
117             addressResult.getTitle());
118         break;
119       case 1:
120         String[] names = addressResult.getNames();
121         String title = names != null ? names[0] : null;
122         searchMap(addressResult.getAddress(), title);
123         break;
124       case 2:
125         dialPhone(addressResult.getPhoneNumbers()[0]);
126         break;
127       case 3:
128         sendEmail(addressResult.getEmails()[0], null, null);
129         break;
130       default:
131         break;
132     }
133   }
134
135   // Overriden so we can hyphenate phone numbers, format birthdays, and bold the name.
136   @Override
137   public CharSequence getDisplayContents() {
138     AddressBookParsedResult result = (AddressBookParsedResult) this.result;
139     StringBuffer contents = new StringBuffer();
140     ParsedResult.maybeAppend(result.getNames(), contents);
141     int namesLength = contents.length();
142
143     String pronunciation = result.getPronunciation();
144     if (pronunciation != null && pronunciation.length() > 0) {
145       contents.append("\n(");
146       contents.append(pronunciation);
147       contents.append(')');
148     }
149
150     ParsedResult.maybeAppend(result.getTitle(), contents);
151     ParsedResult.maybeAppend(result.getOrg(), contents);
152     ParsedResult.maybeAppend(result.getAddress(), contents);
153     String[] numbers = result.getPhoneNumbers();
154     if (numbers != null) {
155       for (String number : numbers) {
156         ParsedResult.maybeAppend(PhoneNumberUtils.formatNumber(number), contents);
157       }
158     }
159     ParsedResult.maybeAppend(result.getEmails(), contents);
160     ParsedResult.maybeAppend(result.getURL(), contents);
161
162     String birthday = result.getBirthday();
163     if (birthday != null && birthday.length() > 0) {
164       Date date;
165       synchronized (DATE_FORMAT) {
166         date = DATE_FORMAT.parse(birthday, new ParsePosition(0));
167       }
168       ParsedResult.maybeAppend(DateFormat.getDateInstance().format(date.getTime()), contents);
169     }
170     ParsedResult.maybeAppend(result.getNote(), contents);
171
172     if (namesLength > 0) {
173       // Bold the full name to make it stand out a bit.
174       Spannable styled = new SpannableString(contents.toString());
175       styled.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, namesLength, 0);
176       return styled;
177     } else {
178       return contents.toString();
179     }
180   }
181
182   @Override
183   public int getDisplayTitle() {
184     return R.string.result_address_book;
185   }
186 }