package jp.sourceforge.tamanegisoul.sa.widget;

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 jp.sourceforge.tamanegisoul.sa.util.DBHelper;
import jp.sourceforge.tamanegisoul.sa.util.LogUtil;

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.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Xml;

public class NationalHolidayQueryProgressDialog extends ProgressDialog {

    private boolean mCanceled;

    public NationalHolidayQueryProgressDialog(Context context) {
        super(context);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setProgressStyle(ProgressDialog.STYLE_SPINNER);
        setMessage("取得中…");
        setCancelable(true);
        setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                mCanceled = true;
            }
        });
    }

    @Override
    public void show() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                updateNationalHoliday();
                dismiss();
            }
        }).start();
        super.show();
    }

    public boolean isCanceled() {
        return mCanceled;
    }
    
    /**
     * 祝日を取得、更新する。
     */
    private void updateNationalHoliday() {
        // 祝日取得
        List<String[]> nationalHolidayList = retrieveNationalHolidayList();
        if(isCanceled()){
            return;
        }
        // 更新
        SQLiteDatabase db = new DBHelper(getContext()).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);
        } catch (IOException e) {
            LogUtil.e("Failed to retrieve NationalHoliday list.", e);
        } catch (XmlPullParserException e) {
            LogUtil.e("Failed to retrieve NationalHoliday list.", e);
        }
        return holidayList;
    }

}
