// Copyright 2011 NPR
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.npr.android.news;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import org.npr.android.util.ArrayUtils;
import org.npr.android.util.DisplayUtils;
import org.npr.android.util.Program;
import org.npr.api.ApiConstants;
import org.npr.api.PublicBroadcastingClient;
import java.io.IOException;
import java.util.*;
public class AllProgramsActivity extends TitleActivity implements
AdapterView.OnItemClickListener {
private static final String LOG_TAG = AllProgramsActivity.class.getName();
private Integer[] nowPlayingIDs;
private ListAdapter listAdapter;
private ListView listView;
private String[] categories;
private final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
listView.setAdapter(listAdapter);
stopIndeterminateProgressIndicator();
break;
default:
Toast.makeText(AllProgramsActivity.this,
getResources().getText(R.string.msg_check_connection),
Toast.LENGTH_LONG)
.show();
}
}
};
@SuppressWarnings("unchecked")
protected int constructList() {
try {
nowPlayingIDs = PublicBroadcastingClient.getNowPlayingIds(this);
List<Program> programs = new Program.ProgramFactory().downloadPrograms(this);
listAdapter = new ProgramListAdapter(categorizePrograms(programs));
if (programs != null) {
return 0;
}
} catch (IOException e) {
Log.e(LOG_TAG, "Error constructing program list", e);
}
return 1;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
categories = getResources().getStringArray(R.array.program_categories);
ViewGroup container = (ViewGroup) findViewById(R.id.Content);
ViewGroup.inflate(this, R.layout.news_topics, container);
listView = (ListView) findViewById(R.id.topic_list);
listView.setOnItemClickListener(this);
initializeList();
}
private void initializeList() {
startIndeterminateProgressIndicator();
Thread listInitThread = new Thread(new Runnable() {
public void run() {
int result = AllProgramsActivity.this.constructList();
handler.sendEmptyMessage(result);
}
});
listInitThread.start();
}
@Override
public CharSequence getMainTitle() {
return getString(R.string.msg_main_subactivity_programs);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
int type = getIntent().getIntExtra(Constants.EXTRA_SUBACTIVITY_ID, -1);
Program item =
((CategorizedProgram) parent.getItemAtPosition(position)).program;
if (item == null) {
return;
}
Intent i = new Intent(this, ProgramStoryListActivity.class);
i.putExtra(Constants.EXTRA_LIVE_STREAM_RSS_URL, item.getLiveStationsUrl());
i.putExtra(Constants.EXTRA_TEASER_ONLY, true);
String grouping = getString(type);
String description = item.getName();
String topicId = item.getNprId();
String url = item.getSource();
if (url != null) {
i.putExtra(Constants.EXTRA_PODCAST_URL, url);
} else {
Map<String, String> params = new HashMap<String, String>();
params.put(ApiConstants.PARAM_ID, topicId);
params.put(ApiConstants.PARAM_FIELDS, ApiConstants.STORY_FIELDS);
params.put(ApiConstants.PARAM_SORT, "assigned");
params.put(ApiConstants.PARAM_DATE, "current");
url =
ApiConstants.instance().createUrl(ApiConstants.STORY_PATH, params);
i.putExtra(Constants.EXTRA_QUERY_URL, url);
}
if (topicId != null && Character.isDigit(topicId.charAt(0))) {
int intId = Integer.parseInt(topicId);
if (nowPlayingIDs != null &&
ArrayUtils.indexOf(nowPlayingIDs, intId) != -1) {
i.putExtra(Constants.EXTRA_ON_AIR, true);
}
}
i.putExtra(Constants.EXTRA_DESCRIPTION, description);
i.putExtra(Constants.EXTRA_GROUPING, grouping);
i.putExtra(Constants.EXTRA_SIZE, 10);
startActivityWithoutAnimation(i);
}
private class CategorizedProgram implements Comparable<CategorizedProgram> {
public final Program program;
public final int categoryIndex;
public final String categoryName;
public CategorizedProgram(int category, Program program) {
this.categoryIndex = category;
this.program = program;
this.categoryName = null;
}
public CategorizedProgram(int category) {
this.categoryIndex = category;
this.program = null;
this.categoryName = categories[categoryIndex];
}
public boolean isHeader() {
return program == null && categoryName != null;
}
@Override
public int compareTo(CategorizedProgram other) {
// Lower category index first
int ret = categoryIndex - other.categoryIndex;
if (ret == 0 && program != null) {
// Sort by order read
ret = program.getSortOrder() - other.program.getSortOrder();
}
return ret;
}
@Override
public String toString() {
return program == null ? categoryName : program.getName();
}
}
private class ProgramListAdapter extends
ArrayAdapter<CategorizedProgram> {
public ProgramListAdapter(List<CategorizedProgram> programList) {
super(AllProgramsActivity.this, R.layout.news_topic_item,
android.R.id.text1, programList);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
CategorizedProgram item = getItem(position);
ImageView icon = (ImageView) v.findViewById(R.id.icon);
if (icon != null) {
int id = -1;
if (item != null && item.program != null) {
String topicId = item.program.getNprId();
if (topicId != null && Character.isDigit(topicId.charAt(0))) {
id = Integer.parseInt(topicId);
}
}
if (nowPlayingIDs != null &&
id != -1 &&
ArrayUtils.indexOf(nowPlayingIDs, id) != -1) {
icon.setVisibility(View.VISIBLE);
} else {
icon.setVisibility(View.INVISIBLE);
}
} else {
Log.e(LOG_TAG, "Could not find 'icon' view in list item at position "
+ position);
}
if (item != null && item.isHeader()) {
v.setEnabled(false);
v.setBackgroundDrawable(
getResources().getDrawable(R.drawable.top_stories_title_background)
);
v.getLayoutParams().height =
DisplayUtils.convertToDIP(getContext(), 30);
((TextView) v.findViewById(android.R.id.text1))
.setTextColor(getResources().getColor(R.color.news_title_text));
} else {
v.setEnabled(true);
v.setBackgroundDrawable(null);
v.getLayoutParams().height =
DisplayUtils.convertToDIP(getContext(), 50);
((TextView) v.findViewById(android.R.id.text1))
.setTextColor(getResources().getColor(R.color.black));
}
return v;
}
}
private List<CategorizedProgram> categorizePrograms(List<Program> programs) {
List<CategorizedProgram> orderedList =
new ArrayList<CategorizedProgram>(programs.size());
// Associate each program with its category
for (Program p : programs) {
int i = getCategoryById(p.getNprId());
if (i < 0) {
i = getCategoryByTitle(p.getName());
}
if (i < 0 ) {
i = categories.length - 1;
}
orderedList.add(new CategorizedProgram(i, p));
}
// Sort them
Collections.sort(orderedList);
// Now add the categories headers themselves
List<CategorizedProgram> listWithHeaders =
new ArrayList<CategorizedProgram>(programs.size() + categories.length);
int oldCategory = -1;
for (CategorizedProgram p : orderedList) {
if (oldCategory != p.categoryIndex) {
listWithHeaders.add(new CategorizedProgram(p.categoryIndex));
oldCategory = p.categoryIndex;
}
listWithHeaders.add(p);
}
return listWithHeaders;
}
// For a given program id or title, what category should it be in?
private static int getCategoryById(String id) {
if (id == null) {
return -1;
}
if (id.equals("2") || id.equals("13") || id.equals("3") || id.equals("5")
|| id.equals("46") || id.equals("7") || id.equals("10")
|| id.equals("38")) {
return 0; // News
} else if (id.equals("35") || id.equals("18")) {
return 1; // Arts & Life
} else if (id.equals("37") || id.equals("20") || id.equals("24")
|| id.equals("39")) {
return 2; // Music
} else if (id.equals("")) {
return 3; // Special Series
}
return -1;
}
private static int getCategoryByTitle(String title) {
if (title == null) {
return -1;
}
if (title.equals("Weekends on All Things Considered")
|| title.equals("Science Friday") || title.equals("Diane Rehm (WAMU)")
|| title.equals("On the Media (WNYC)")) {
return 0; // News
} else if (title.equals("Your Health") || title.equals("Radiolab (WNYC)")
|| title.equals("Snap Judgment")) {
return 1; // Arts & Life
} else if (title.equals("Thistle & Shamrock")
|| title.equals("From the Top")) {
return 2; // Music
} else if (title.equals("Planet Money")) {
return 3; // Special Series
}
return -1;
}
}