/*
 * Copyright (C) 2006 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 android.widget;

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.view.View;

/**
 * An easy adapter to map columns from a cursor to TextViews or ImageViews
 * defined in an XML file. You can specify which columns you want, which views
 * you want to display the columns, and the XML file that defines the appearance
 * of these views. Separate XML files for child and groups are possible.
 * TextViews bind the values to their text property (see
 * {@link TextView#setText(CharSequence)}). ImageViews bind the values to their
 * image's Uri property (see {@link ImageView#setImageURI(android.net.Uri)}).
 */
public abstract class SimpleCursorTreeAdapter extends ResourceCursorTreeAdapter {
    /** The indices of columns that contain data to display for a group. */
    private int[] mGroupFrom;
    /**
     * The View IDs that will display a group's data fetched from the
     * corresponding column.
     */
    private int[] mGroupTo;

    /** The indices of columns that contain data to display for a child. */
    private int[] mChildFrom;
    /**
     * The View IDs that will display a child's data fetched from the
     * corresponding column.
     */
    private int[] mChildTo;
    
    /**
     * Constructor.
     * 
     * @param context The context where the {@link ExpandableListView}
     *            associated with this {@link SimpleCursorTreeAdapter} is
     *            running
     * @param cursor The database cursor
     * @param collapsedGroupLayout The resource identifier of a layout file that
     *            defines the views for a collapsed group. The layout file
     *            should include at least those named views defined in groupTo.
     * @param expandedGroupLayout The resource identifier of a layout file that
     *            defines the views for an expanded group. The layout file
     *            should include at least those named views defined in groupTo.
     * @param groupFrom A list of column names that will be used to display the
     *            data for a group.
     * @param groupTo The group views (from the group layouts) that should
     *            display column in the "from" parameter. These should all be
     *            TextViews or ImageViews. The first N views in this list are
     *            given the values of the first N columns in the from parameter.
     * @param childLayout The resource identifier of a layout file that defines
     *            the views for a child (except the last). The layout file
     *            should include at least those named views defined in childTo.
     * @param lastChildLayout The resource identifier of a layout file that
     *            defines the views for the last child within a group. The
     *            layout file should include at least those named views defined
     *            in childTo.
     * @param childFrom A list of column names that will be used to display the
     *            data for a child.
     * @param childTo The child views (from the child layouts) that should
     *            display column in the "from" parameter. These should all be
     *            TextViews or ImageViews. The first N views in this list are
     *            given the values of the first N columns in the from parameter.
     */
    public SimpleCursorTreeAdapter(Context context, Cursor cursor, int collapsedGroupLayout,
            int expandedGroupLayout, String[] groupFrom, int[] groupTo, int childLayout,
            int lastChildLayout, String[] childFrom, int[] childTo) {
        super(context, cursor, collapsedGroupLayout, expandedGroupLayout, childLayout,
                lastChildLayout);
        init(groupFrom, groupTo, childFrom, childTo);
    }

    /**
     * Constructor.
     * 
     * @param context The context where the {@link ExpandableListView}
     *            associated with this {@link SimpleCursorTreeAdapter} is
     *            running
     * @param cursor The database cursor
     * @param collapsedGroupLayout The resource identifier of a layout file that
     *            defines the views for a collapsed group. The layout file
     *            should include at least those named views defined in groupTo.
     * @param expandedGroupLayout The resource identifier of a layout file that
     *            defines the views for an expanded group. The layout file
     *            should include at least those named views defined in groupTo.
     * @param groupFrom A list of column names that will be used to display the
     *            data for a group.
     * @param groupTo The group views (from the group layouts) that should
     *            display column in the "from" parameter. These should all be
     *            TextViews or ImageViews. The first N views in this list are
     *            given the values of the first N columns in the from parameter.
     * @param childLayout The resource identifier of a layout file that defines
     *            the views for a child. The layout file
     *            should include at least those named views defined in childTo.
     * @param childFrom A list of column names that will be used to display the
     *            data for a child.
     * @param childTo The child views (from the child layouts) that should
     *            display column in the "from" parameter. These should all be
     *            TextViews or ImageViews. The first N views in this list are
     *            given the values of the first N columns in the from parameter.
     */
    public SimpleCursorTreeAdapter(Context context, Cursor cursor, int collapsedGroupLayout,
            int expandedGroupLayout, String[] groupFrom, int[] groupTo,
            int childLayout, String[] childFrom, int[] childTo) {
        super(context, cursor, collapsedGroupLayout, expandedGroupLayout, childLayout);
        init(groupFrom, groupTo, childFrom, childTo);
    }

    /**
     * Constructor.
     * 
     * @param context The context where the {@link ExpandableListView}
     *            associated with this {@link SimpleCursorTreeAdapter} is
     *            running
     * @param cursor The database cursor
     * @param groupLayout The resource identifier of a layout file that defines
     *            the views for a group. The layout file should include at least
     *            those named views defined in groupTo.
     * @param groupFrom A list of column names that will be used to display the
     *            data for a group.
     * @param groupTo The group views (from the group layouts) that should
     *            display column in the "from" parameter. These should all be
     *            TextViews or ImageViews. The first N views in this list are
     *            given the values of the first N columns in the from parameter.
     * @param childLayout The resource identifier of a layout file that defines
     *            the views for a child. The layout file should include at least
     *            those named views defined in childTo.
     * @param childFrom A list of column names that will be used to display the
     *            data for a child.
     * @param childTo The child views (from the child layouts) that should
     *            display column in the "from" parameter. These should all be
     *            TextViews or ImageViews. The first N views in this list are
     *            given the values of the first N columns in the from parameter.
     */
    public SimpleCursorTreeAdapter(Context context, Cursor cursor, int groupLayout,
            String[] groupFrom, int[] groupTo, int childLayout, String[] childFrom,
            int[] childTo) {
        super(context, cursor, groupLayout, childLayout);
        init(groupFrom, groupTo, childFrom, childTo);
    }

    private void init(String[] groupFromNames, int[] groupTo, String[] childFromNames,
            int[] childTo) {
        mGroupTo = groupTo;
        
        mChildTo = childTo;
        
        // Get the group cursor column indices, the child cursor column indices will come
        // when needed
        initGroupFromColumns(groupFromNames);
        
        // Get a temporary child cursor to init the column indices
        if (getGroupCount() > 0) {
            MyCursorHelper tmpCursorHelper = getChildrenCursorHelper(0, true);
            if (tmpCursorHelper != null) {
                initChildrenFromColumns(childFromNames, tmpCursorHelper.getCursor());
                deactivateChildrenCursorHelper(0);
            }
        }
    }
    
    private void initFromColumns(Cursor cursor, String[] fromColumnNames, int[] fromColumns) {
        for (int i = fromColumnNames.length - 1; i >= 0; i--) {
            fromColumns[i] = cursor.getColumnIndexOrThrow(fromColumnNames[i]);
        }
    }
    
    private void initGroupFromColumns(String[] groupFromNames) {
        mGroupFrom = new int[groupFromNames.length];
        initFromColumns(mGroupCursorHelper.getCursor(), groupFromNames, mGroupFrom);
    }

    private void initChildrenFromColumns(String[] childFromNames, Cursor childCursor) {
        mChildFrom = new int[childFromNames.length];
        initFromColumns(childCursor, childFromNames, mChildFrom);
    }
    
    private void bindView(View view, Context context, Cursor cursor, int[] from, int[] to) {
        for (int i = 0; i < to.length; i++) {
            View v = view.findViewById(to[i]);
            if (v != null) {
                String text = cursor.getString(from[i]);
                if (text == null) {
                    text = "";
                }
                if (v instanceof TextView) {
                    ((TextView) v).setText(text);
                } else if (v instanceof ImageView) {
                    setViewImage((ImageView) v, text);
                } else {
                    throw new IllegalStateException("SimpleCursorAdapter can bind values only to" +
                            " TextView and ImageView!");
                }
            }
        }
    }
    
    @Override
    protected void bindChildView(View view, Context context, Cursor cursor, boolean isLastChild) {
        bindView(view, context, cursor, mChildFrom, mChildTo);
    }

    @Override
    protected void bindGroupView(View view, Context context, Cursor cursor, boolean isExpanded) {
        bindView(view, context, cursor, mGroupFrom, mGroupTo);
    }

    /**
     * Called by bindView() to set the image for an ImageView. By default, the
     * value will be treated as a Uri. Intended to be overridden by Adapters
     * that need to filter strings retrieved from the database.
     * 
     * @param v ImageView to receive an image
     * @param value the value retrieved from the cursor
     */
    protected void setViewImage(ImageView v, String value) {
        try {
            v.setImageResource(Integer.parseInt(value));
        } catch (NumberFormatException nfe) {
            v.setImageURI(Uri.parse(value));
        }
    }
}
