/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * 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 com.android.browser.util;

import android.content.Context;
import android.database.Cursor;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.os.Process;
import android.os.SystemProperties;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.BaseAdapter;
import android.widget.CursorAdapter;

import com.android.browser.R;

import java.lang.ref.WeakReference;

public abstract class ThreadedCursorAdapter<T> extends BaseAdapter {

    private static final String LOGTAG = "BookmarksThreadedAdapter";
    private static final boolean DEBUG = false;

    private Context mContext;
    private Object mCursorLock = new Object();
    private CursorAdapter mCursorAdapter;
    private T mLoadingObject;
    private Handler mLoadHandler;
    private Handler mHandler;
    private int mSize;
    private boolean mHasCursor;
    private long mGeneration;

    private class LoadContainer {
        WeakReference<View> view;
        int position;
        T bind_object;
        Adapter owner;
        boolean loaded;
        long generation;
    }

    public ThreadedCursorAdapter(Context context, Cursor c) {
        mContext = context;
        mHasCursor = (c != null);
        mCursorAdapter = new CursorAdapter(context, c, 0) {

            @Override
            public View newView(Context context, Cursor cursor, ViewGroup parent) {
                throw new IllegalStateException("not supported");
            }

            @Override
            public void bindView(View view, Context context, Cursor cursor) {
                throw new IllegalStateException("not supported");
            }

            @Override
            public void notifyDataSetChanged() {
                super.notifyDataSetChanged();
                mSize = getCount();
                mGeneration++;
                ThreadedCursorAdapter.this.notifyDataSetChanged();
            }

            @Override
            public void notifyDataSetInvalidated() {
                super.notifyDataSetInvalidated();
                mSize = getCount();
                mGeneration++;
                ThreadedCursorAdapter.this.notifyDataSetInvalidated();
            }

        };
        mSize = mCursorAdapter.getCount();
        HandlerThread thread = new HandlerThread("threaded_adapter_" + this,
                Process.THREAD_PRIORITY_BACKGROUND);
        thread.start();
        mLoadHandler = new Handler(thread.getLooper()) {
            @SuppressWarnings("unchecked")
            @Override
            public void handleMessage(Message msg) {
                if (DEBUG) {
                    Log.d(LOGTAG, "loading: " + msg.what);
                }
                loadRowObject(msg.what, (LoadContainer) msg.obj);
            }
        };
        mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                @SuppressWarnings("unchecked")
                LoadContainer container = (LoadContainer) msg.obj;
                if (container == null) {
                    return;
                }
                View view = container.view.get();
                if (view == null
                        || container.owner != ThreadedCursorAdapter.this
                        || container.position != msg.what
                        || view.getWindowToken() == null
                        || container.generation != mGeneration) {
                    return;
                }
                container.loaded = true;
                bindView(view, container.bind_object);
            }
        };
    }

    @Override
    public int getCount() {
        return mSize;
    }

    @Override
    public Cursor getItem(int position) {
        return (Cursor) mCursorAdapter.getItem(position);
    }

    @Override
    public long getItemId(int position) {
        synchronized (mCursorLock) {
            return getItemId(getItem(position));
        }
    }

    private void loadRowObject(int position, LoadContainer container) {
        if (container == null
                || container.position != position
                || container.owner != ThreadedCursorAdapter.this
                || container.view.get() == null) {
            return;
        }
        synchronized (mCursorLock) {
            Cursor c = (Cursor) mCursorAdapter.getItem(position);
            if (c == null || c.isClosed()) {
                return;
            }
            container.bind_object = getRowObject(c, container.bind_object);
        }
        mHandler.obtainMessage(position, container).sendToTarget();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = newView(mContext, parent);
        }
        @SuppressWarnings("unchecked")
        LoadContainer container = (LoadContainer) convertView.getTag(R.id.load_object);
        if (container == null) {
            container = new LoadContainer();
            container.view = new WeakReference<View>(convertView);
            convertView.setTag(R.id.load_object, container);
        }
        if (container.position == position
                && container.owner == this
                && container.loaded
                && container.generation == mGeneration) {
            bindView(convertView, container.bind_object);
        } else {
            bindView(convertView, cachedLoadObject());
            if (mHasCursor) {
                container.position = position;
                container.loaded = false;
                container.owner = this;
                container.generation = mGeneration;
                mLoadHandler.obtainMessage(position, container).sendToTarget();
            }
        }
        return convertView;
    }

    private T cachedLoadObject() {
        if (mLoadingObject == null) {
            mLoadingObject = getLoadingObject();
        }
        return mLoadingObject;
    }

    public void changeCursor(Cursor cursor) {
        mLoadHandler.removeCallbacksAndMessages(null);
        mHandler.removeCallbacksAndMessages(null);
        synchronized (mCursorLock) {
            mHasCursor = (cursor != null);
            mCursorAdapter.changeCursor(cursor);
        }
    }

    public abstract View newView(Context context, ViewGroup parent);
    public abstract void bindView(View view, T object);
    public abstract T getRowObject(Cursor c, T recycleObject);
    public abstract T getLoadingObject();
    protected abstract long getItemId(Cursor c);
}