package jp.sourceforge.tamanegisoul.sa;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Xml;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

/**
 * 休日一覧画面
 */
public class HolidayListActivity extends ListActivity {

    private static final int MENU_ADD = 1; // 追加メニュー
    private static final int MENU_ADD_NATIONAL_HOLIDAY = 2; // 祝日追加メニュー
    private static final int MENU_REMOVE_ALL = 3; // 全削除メニュー

    private Cursor mCursor; // ListViewのデータカーソル

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.holiday_list);
        setTitle(getResources().getString(R.string.holiday_list));

        SQLiteDatabase db = new DBHelper(this).getReadableDatabase();
        mCursor = db.query(DBHelper.T_HOLIDAY, null, null, null, null, null, DBHelper.C_HOLIDAY_DATE);

        // リストの設定
        SimpleCursorAdapter ca = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, mCursor, new String[] { DBHelper.C_HOLIDAY_DATE,
                DBHelper.C_HOLIDAY_NAME }, new int[] { android.R.id.text1, android.R.id.text2 });
        setListAdapter(ca);

        // リスト項目の選択リスナー
        getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // 休日IDを渡して休日設定画面を起動
                Intent i = new Intent(parent.getContext(), HolidayActivity.class);
                i.putExtra(DBHelper.C_HOLIDAY_ID, mCursor.getInt(mCursor.getColumnIndex(DBHelper.C_HOLIDAY_ID)));
                startActivity(i);
            }
        });

    }

    @Override
    protected void onStart() {
        super.onStart();
        mCursor.requery();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mCursor.close();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuItem menuItem = menu.add(Menu.NONE, MENU_ADD, Menu.NONE, R.string.add_holiday);
        menuItem.setIcon(android.R.drawable.ic_menu_add);

        menuItem = menu.add(Menu.NONE, MENU_ADD_NATIONAL_HOLIDAY, Menu.NONE, R.string.add_national_holiday);
        menuItem.setIcon(android.R.drawable.ic_menu_rotate);

        menuItem = menu.add(Menu.NONE, MENU_REMOVE_ALL, Menu.NONE, R.string.remove_all);
        menuItem.setIcon(android.R.drawable.ic_menu_delete);

        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
        switch (item.getItemId()) {
        case MENU_ADD:
            // 休日IDを渡さずに休日設定画面を起動
            startActivity(new Intent(this, HolidayActivity.class));
            break;
        case MENU_ADD_NATIONAL_HOLIDAY:
            // プログレスダイアログ
            final ProgressDialog mProgressDialog = new ProgressDialog(this);
            mProgressDialog.setMessage("取得中…");
            mProgressDialog.setIndeterminate(true);
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            mProgressDialog.setCancelable(true);
            mProgressDialog.show();
            // UIの更新は別スレッドからできないのでリスナーを使う
            mProgressDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
                @Override
                public void onDismiss(DialogInterface dialog) {
                    mCursor.requery();
                }
            });
            new Thread(new Runnable() {
                @Override
                public void run() {
                    updateNationalHoliday();
                    mProgressDialog.dismiss();
                }
            }).start();
            break;
        case MENU_REMOVE_ALL:
            AlertDialog d = new AlertDialog.Builder(HolidayListActivity.this).create();
            d.setMessage(getResources().getString(R.string.confirm_delete));
            d.setButton(AlertDialog.BUTTON_POSITIVE, getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    SQLiteDatabase db = new DBHelper(HolidayListActivity.this).getWritableDatabase();
                    db.delete(DBHelper.T_HOLIDAY, null, null);
                    db.close();
                    mCursor.requery();
                    dialog.dismiss();
                }
            });
            d.setButton(AlertDialog.BUTTON_NEGATIVE, getResources().getString(android.R.string.cancel), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
            d.show();
            break;
        }
        return super.onMenuItemSelected(featureId, item);
    }

    /**
     * 祝日を取得、更新する。
     */
    private void updateNationalHoliday() {
        // 祝日取得
        List<String[]> nationalHolidayList = retrieveNationalHolidayList();
        // 更新
        SQLiteDatabase db = new DBHelper(this).getWritableDatabase();
        for (String[] holidayDef : nationalHolidayList) {
            Cursor c = db.query(DBHelper.T_HOLIDAY, null, "date = ? and name = ?", new String[] { holidayDef[0], holidayDef[1] }, null, null, null);
            if (!c.moveToFirst()) {
                // 結果が0件(同じものが未登録)の場合は追加する
                ContentValues v = new ContentValues();
                v.put(DBHelper.C_HOLIDAY_DATE, holidayDef[0]);
                v.put(DBHelper.C_HOLIDAY_NAME, holidayDef[1]);
                db.insert(DBHelper.T_HOLIDAY, null, v);
            }
            c.close();
        }
        db.close();
    }

    /**
     * 祝日を取得する
     * @return 祝日リスト(各要素の配列の1つ目は日付、2つ目は名称)
     */
    private List<String[]> retrieveNationalHolidayList() {
        List<String[]> holidayList = new ArrayList<String[]>();
        try {
            // 今年と来年の祝日を取得
            int year = Calendar.getInstance().get(Calendar.YEAR);
            String url = String
                    .format(
                            "http://www.google.com/calendar/feeds/japanese__ja@holiday.calendar.google.com/public/full?start-min=%s-01-01&start-max=%s-12-31&fields=entry(title,gd:when)&orderby=starttime&sortorder=a&max-results=100",
                            year, year + 1);
            HttpGet request = new HttpGet(url);
            HttpClient httpclient = new DefaultHttpClient();
            HttpResponse response = (HttpResponse) httpclient.execute(request);
            BufferedReader reader = new BufferedReader(new InputStreamReader(new BufferedHttpEntity(response.getEntity()).getContent()));
            // 結果をパース
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(reader);
            String currentTagName = null;
            String[] currentHoliday = null;
            for (int eventType = parser.getEventType(); eventType != XmlPullParser.END_DOCUMENT; eventType = parser.next()) {
                switch (eventType) {
                case XmlPullParser.START_TAG:
                    currentTagName = parser.getName();
                    if (currentTagName.equals("when")) {
                        currentHoliday[0] = parser.getAttributeValue(null, "startTime");
                        holidayList.add(currentHoliday);
                    }
                    break;
                case XmlPullParser.TEXT:
                    if (currentTagName.equals("title")) {
                        currentHoliday = new String[] { null, parser.getText() };
                    }
                    break;
                }
            }
            reader.close();
        } catch (ClientProtocolException e) {
            LogUtil.e("Failed to retrieve NationalHoliday list.", e);
            Toast.makeText(this, "Failed to retrieve NationalHoliday list.", 500);
        } catch (IOException e) {
            LogUtil.e("Failed to retrieve NationalHoliday list.", e);
            Toast.makeText(this, "Failed to retrieve NationalHoliday list.", 500);
        } catch (XmlPullParserException e) {
            LogUtil.e("Failed to retrieve NationalHoliday list.", e);
            Toast.makeText(this, "Failed to retrieve NationalHoliday list.", 500);
        }
        return holidayList;
    }
}
