package com.aincc.seoulexcursion.ui.scene.parks;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.aincc.lib.common.annotation.InjectView;
import com.aincc.lib.network.common.BaseTrans;
import com.aincc.lib.network.common.BaseTransEx;
import com.aincc.lib.network.http.HttpParam;
import com.aincc.lib.ui.widget.list.section.AmazingListView;
import com.aincc.lib.util.ImageLoader;
import com.aincc.lib.util.ImageWorker.ImageWorkerAdapter;
import com.aincc.lib.util.PreferencesUtil;
import com.aincc.seoulexcursion.App;
import com.aincc.seoulexcursion.R;
import com.aincc.seoulexcursion.ui.Constants;
import com.aincc.seoulexcursion.ui.SeoulBaseActivity;
import com.aincc.seoulexcursion.ui.control.SectionAdapter;
import com.aincc.seoulexcursion.ui.widget.Navibar;
import com.aincc.seoulexcursion.ui.widget.Navisheet.OptionSelected;
import com.aincc.seoulexcursion.util.Logger;
import com.aincc.seoulexcursion.util.SeoulFont;
import com.aincc.seoulopenapi.OpenAPI;
import com.aincc.seoulopenapi.ServiceExecutor;
import com.aincc.seoulopenapi.model.ParkInfo;
import com.aincc.seoulopenapi.model.TotalCount;
import com.aincc.seoulopenapi.network.OpenBase;
import com.aincc.seoulopenapi.openapi.park.OpenParkInfo;
import com.aincc.seoulopenapi.openapi.park.OpenParkInfoTotalCount;
/**
*
* <h3><b>ParksActivity</b></h3></br>
*
* 공원목록 표시 <br>
*
* @author aincc@barusoft.com
* @version 1.0.0
* @since 1.0.0
*/
public class ParksActivity extends SeoulBaseActivity implements OptionSelected
{
/**
* <pre>
* 공원정보
* 세부화면에서 지도에 각 공원의 위치를 표시하기 위하여 static 으로 관리
* </pre>
*/
private static List<Pair<String, List<ParkInfo>>> listdata = new ArrayList<Pair<String, List<ParkInfo>>>();
/**
* 상단 네비게이션 바
*/
@InjectView
private Navibar navibar;
/**
* 공원 리스트뷰
*/
@InjectView
private AmazingListView listview;
/**
* 공원 어댑터
*/
private SectionParksAdapter<ParkInfo> adapter;
/**
* 옵션정보
*/
private List<Pair<String, List<String>>> options;
/**
* 옵션 1 지역
*/
private int optionSelected1 = 0;
/**
* 옵션 2 전체 (구)
*/
private int optionSelected2 = 0;
/**
* 이미지 다운로더
*/
private ImageLoader imageLoader;
/**
* 이미지 어댑터
*/
private ParkImageAdapter imageAdapter;
/**
* 현재 조회된 공원정보 가져오기
*
* @since 1.0.0
* @return 공원목록
*/
public static List<Pair<String, List<ParkInfo>>> getParks()
{
return listdata;
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_parks);
mappingViews(this);
initializeUI();
}
@Override
protected void initializeUI()
{
super.initializeUI();
if (null == imageAdapter)
{
imageAdapter = new ParkImageAdapter();
}
if (null == adapter)
{
adapter = new SectionParksAdapter<ParkInfo>();
adapter.setList(listdata);
listview.setAdapter(adapter);
}
listview.setPinnedHeaderView(LayoutInflater.from(this).inflate(R.layout.cell_header_parks, listview, false));
}
@Override
protected void initializeNavibar()
{
super.initializeNavibar();
navibar.setTypeface(SeoulFont.getInstance().getSeoulHangang());
navibar.setActionBack(new OnClickListener()
{
@Override
public void onClick(View v)
{
finish();
}
});
navibar.setActionFunc(new OnClickListener()
{
@Override
public void onClick(View v)
{
Intent intent = new Intent(context, ParksSearchActivity.class);
startActivity(intent);
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
});
navibar.setActionFuncIcon(drawable(R.drawable.ic_action_search));
// 제목 설정
navibar.setTitle(string(R.string.title_activity_parks));
if (null == options)
{
options = new ArrayList<Pair<String, List<String>>>();
options.add(new Pair<String, List<String>>(string(R.string.park_zone), Arrays.asList(stringArray(R.array.seoul_jurisdiction))));
optionSelected1 = PreferencesUtil.getInt(context, Constants.PREFS_SETTING_FILE, Constants.PREFS_KEY_LAST_PARKOPT1, Constants.OPTION_START_INDEX);
optionSelected2 = PreferencesUtil.getInt(context, Constants.PREFS_SETTING_FILE, Constants.PREFS_KEY_LAST_PARKOPT2, Constants.OPTION_START_INDEX);
navibar.setOptionData(options, optionSelected1, optionSelected2);
navibar.setOptionListener(this);
navibar.setOptionText(optionSelected1, optionSelected2);
}
}
@Override
public void finish()
{
super.finish();
}
@Override
protected void onResume()
{
super.onResume();
imageLoader = App.getImageLoader(imageAdapter);
// 공원전체개수가 리셋된 경우
if (0 == parkTotalCount.get())
{
clearData();
requestTotalCount();
}
// 공원전체개수가 설정되어있고, 공원리스트가 비어있는 경우
else if (listdata.isEmpty() && 0 != parkTotalCount.get())
{
request();
}
// 2012.09.01 aincc : 화면갱신 처리.
else
{
refreshData();
}
}
@Override
protected void onPause()
{
super.onPause();
ServiceExecutor.getInstance().cancelAll();
}
@Override
protected void onStop()
{
super.onStop();
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
initializeUI();
}
@Override
public void OnOptionSelected(int optionSelected1, int optionSelected2)
{
this.optionSelected1 = optionSelected1;
this.optionSelected2 = optionSelected2;
PreferencesUtil.setInt(context, Constants.PREFS_SETTING_FILE, Constants.PREFS_KEY_LAST_PARKOPT1, optionSelected1);
PreferencesUtil.setInt(context, Constants.PREFS_SETTING_FILE, Constants.PREFS_KEY_LAST_PARKOPT2, optionSelected2);
request();
}
/**
* 로딩표시
*
* @since 1.0.0
*/
private void showLoading()
{
startProgress("", true, new OnCancelListener()
{
@Override
public void onCancel(DialogInterface dialog)
{
ServiceExecutor.getInstance().cancelAll();
loadingAccCount.set(ATOMIC_LOADING_INIT);
}
}, Constants.COLOR_BLACK);
}
/**
* 데이터 초기화 후 갱신
*
* @since 1.0.0
*/
private void clearData()
{
adapter.clear();
refreshData();
}
/**
* 데이터 갱신
*
* @since 1.0.0
*/
synchronized private void refreshData()
{
runOnUiThread(new Runnable()
{
@Override
public void run()
{
adapter.notifyDataSetChanged();
}
});
}
/**
*
* <h3><b>SectionParksAdapter</b></h3></br>
*
* 공원정보 어댑터
*
* @author aincc@barusoft.com
* @version 1.0.0
* @since 1.0.0
*/
class SectionParksAdapter<T> extends SectionAdapter<T>
{
@SuppressWarnings("unchecked")
@Override
public View getAmazingView(final int position, View convertView, ViewGroup parent)
{
View view = convertView;
ViewHolder viewHolder = null;
if (null == convertView)
{
view = getLayoutInflater().inflate(R.layout.cell_parks, null);
viewHolder = new ViewHolder();
viewHolder.cellSelector = (LinearLayout) view.findViewById(R.id.cellSelector);
viewHolder.loading = (ProgressBar) view.findViewById(R.id.loading);
viewHolder.parkImg = (ImageView) view.findViewById(R.id.image);
viewHolder.P_PARK = (TextView) view.findViewById(R.id.P_PARK);
viewHolder.P_ZONE = (TextView) view.findViewById(R.id.P_ZONE);
viewHolder.P_ADMINTEL = (TextView) view.findViewById(R.id.P_ADMINTEL);
viewHolder.P_PARK.setTypeface(SeoulFont.getInstance().getSeoulHangang());
viewHolder.P_ZONE.setTypeface(SeoulFont.getInstance().getSeoulHangang());
viewHolder.P_ADMINTEL.setTypeface(SeoulFont.getInstance().getSeoulHangang());
view.setTag(viewHolder);
}
else
{
viewHolder = (ViewHolder) view.getTag();
}
viewHolder.cellSelector.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
Intent intent = new Intent(context, ParksDetailActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable(Constants.EXTRA_KEY_PARK_INFO, (ParkInfo) getItem(position));
bundle.putInt(Constants.EXTRA_KEY_PARK_DETAIL_FROM, 0);
intent.putExtras(bundle);
startActivity(intent);
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
});
ParkInfo item = (ParkInfo) getItem(position);
imageLoader.loadImage(item.P_IMG, viewHolder.parkImg);
viewHolder.P_PARK.setText(item.P_PARK);
viewHolder.P_ZONE.setText(item.P_ZONE);
viewHolder.P_ADMINTEL.setText(item.P_ADMINTEL);
return view;
}
/**
*
* <h3><b>ViewHolder</b></h3></br>
*
* @author aincc@barusoft.com
* @version 1.0.0
* @since 1.0.0
*/
class ViewHolder
{
LinearLayout cellSelector;
ProgressBar loading;
ImageView parkImg;
TextView P_PARK;
TextView P_ZONE;
TextView P_ADMINTEL;
}
}
/**
*
* <h3><b>ParkImageAdapter</b></h3></br>
*
* @author aincc@barusoft.com
* @version 1.0.0
* @since 1.0.0
*/
class ParkImageAdapter extends ImageWorkerAdapter
{
@Override
public Object getItem(int num)
{
if (null != listdata)
{
int c = 0;
for (int ii = 0; ii < listdata.size(); ii++)
{
if (num >= c && num < c + listdata.get(ii).second.size())
{
return listdata.get(ii).second.get(num - c).P_IMG;
}
c += listdata.get(ii).second.size();
}
}
return null;
}
@Override
public int getSize()
{
if (null != listdata)
{
int res = 0;
for (int ii = 0; ii < listdata.size(); ii++)
{
res += listdata.get(ii).second.size();
}
return res;
}
return 0;
}
}
/**
*
* <h3><b>ZoneComparator</b></h3></br>
*
* @author aincc@barusoft.com
* @version 1.0.0
* @since 1.0.0
*/
class ZoneComparator implements Comparator<ParkInfo>
{
@Override
public int compare(ParkInfo lhs, ParkInfo rhs)
{
return lhs.P_ZONE.compareToIgnoreCase(rhs.P_ZONE);
}
}
// ///////////////////////////////////////////////////////////////////////////////////////////
// 이하 OpenAPI 연동
// ///////////////////////////////////////////////////////////////////////////////////////////
/**
* 공원 전체 개수
*/
private AtomicInteger parkTotalCount = new AtomicInteger(0);
/**
* 요청 누적 계수
*/
private AtomicInteger requestAccCount = new AtomicInteger(0);
@Override
public void iNetEnabled()
{
super.iNetEnabled();
}
@Override
public void iNetDisabled()
{
}
@Override
public boolean iNetListenedTransaction(BaseTrans tr)
{
if (0 < requestAccCount.get())
{
requestAccCount.decrementAndGet();
}
HttpParam param = (HttpParam) tr.getParam();
if (((OpenBase) tr).isError())
{
handleError(tr);
return false;
}
switch (OpenAPI.valueOf(param.getRequestKey()))
{
case PARK_INFO_TOTAL_COUNT:
handleOpenParkInfoTotalCount(tr);
break;
case PARK_INFO:
case PARK_INFO_BY_ADDRESS:
case PARK_INFO_BY_PARKNAME:
handleOpenParkInfo(tr);
break;
case UNKNOWN:
default:
break;
}
return super.iNetListenedTransaction(tr);
}
@Override
public boolean iNetListenedError(BaseTransEx ex)
{
if (0 < requestAccCount.get())
{
requestAccCount.decrementAndGet();
}
return super.iNetListenedError(ex);
}
/**
* 최초 요청 및 옵션변경시 요청
*
* @since 1.0.0
*/
private void request()
{
// 지역선택
if (0 == optionSelected1)
{
String zone = options.get(optionSelected1).second.get(optionSelected2);
// Logger.d1(LOG, "selected zone : " + zone);
if (0 == optionSelected2)
{
clearData();
requestParkInfo(Constants.INIT_START_INDEX, parkTotalCount.get());
}
else
{
clearData();
requestSearch(zone, Constants.SEARCH_BY_ADDR, Constants.INIT_START_INDEX, parkTotalCount.get());
}
}
}
/**
* 공원 전체개수 요청
*
* @since 1.0.0
*/
private void requestTotalCount()
{
showLoading();
requestAccCount.incrementAndGet();
ServiceExecutor.getInstance().getParkInfoTotalCount(OpenAPI.PARK_INFO_TOTAL_COUNT.name(), listener, OpenAPI.PARK_INFO_TOTAL_COUNT, null);
}
/**
* 공원정보 조회 요청
*
* @since 1.0.0
* @param start
* @param end
*/
private void requestParkInfo(int start, int end)
{
showLoading();
requestAccCount.incrementAndGet();
ServiceExecutor.getInstance().getParkInfo(OpenAPI.PARK_INFO.name(), listener, start, end, OpenAPI.PARK_INFO, null);
}
/**
* 공원정보 검색 요청
*
* @since 1.0.0
* @param start
* @param end
*/
private void requestSearch(String keyword, int searchType, int start, int end)
{
showLoading();
requestAccCount.incrementAndGet();
switch (searchType)
{
case Constants.SEARCH_BY_ADDR:
ServiceExecutor.getInstance().getParkInfo(OpenAPI.PARK_INFO_BY_ADDRESS.name(), listener, start, end, OpenAPI.PARK_INFO_BY_ADDRESS, keyword);
break;
case Constants.SEARCH_BY_PARK:
ServiceExecutor.getInstance().getParkInfo(OpenAPI.PARK_INFO_BY_PARKNAME.name(), listener, start, end, OpenAPI.PARK_INFO_BY_PARKNAME, keyword);
break;
}
}
/**
*
* @since 1.0.0
* @param tr
*/
private void handleError(BaseTrans tr)
{
OpenBase item = (OpenBase) tr;
Logger.d1(LOG, "error >> " + item.getErrorInfoType().getCode());
Logger.d1(LOG, " " + item.getErrorInfoType().getTitle(this));
Logger.d1(LOG, " " + item.getErrorInfoType().getMsg(this));
Toast.makeText(context, string(R.string.failed_request), Toast.LENGTH_SHORT).show();
}
/**
* 공원 전체개수 정보 처리
*
* @since 1.0.0
* @param tr
*/
private void handleOpenParkInfoTotalCount(BaseTrans tr)
{
OpenParkInfoTotalCount item = (OpenParkInfoTotalCount) tr;
if (!item.infos.isEmpty())
{
Iterator<TotalCount> it = item.infos.iterator();
if (it.hasNext())
{
parkTotalCount.set(Integer.parseInt(it.next().TOTALCNT));
Logger.d1(LOG, "handleOpenParkInfoTotalCount: totalcount = " + parkTotalCount.get());
request();
}
}
}
/**
* 공원정보 처리
*
* @since 1.0.0
* @param tr
*/
private void handleOpenParkInfo(BaseTrans tr)
{
OpenParkInfo item = (OpenParkInfo) tr;
if (!item.infos.isEmpty())
{
Collections.sort((List<ParkInfo>) item.infos, new ZoneComparator());
Iterator<ParkInfo> it = item.infos.iterator();
String prevSection = null;
List<ParkInfo> section = null;
do
{
ParkInfo info = it.next();
if (null == prevSection)
{
prevSection = info.P_ZONE;
section = new ArrayList<ParkInfo>();
section.add(info);
}
else if (prevSection.equalsIgnoreCase(info.P_ZONE))
{
section.add(info);
}
else
{
listdata.add(new Pair<String, List<ParkInfo>>(prevSection, section));
prevSection = info.P_ZONE;
section = new ArrayList<ParkInfo>();
section.add(info);
}
}
while (it.hasNext());
if (null != prevSection && null != section)
{
listdata.add(new Pair<String, List<ParkInfo>>(prevSection, section));
}
refreshData();
}
else
{
Toast.makeText(context, string(R.string.empty_data), Toast.LENGTH_SHORT).show();
}
}
}