/*
 * Copyright (C) 2008 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.settings.accounts;

import android.accounts.Account;
import android.content.Context;
import android.preference.CheckBoxPreference;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;

import com.android.settings.R;
import com.android.settings.widget.AnimatedImageView;

public class SyncStateCheckBoxPreference extends CheckBoxPreference {

    private boolean mIsActive = false;
    private boolean mIsPending = false;
    private boolean mFailed = false;
    private Account mAccount;
    private String mAuthority;

    /**
     * A mode for this preference where clicking does a one-time sync instead of
     * toggling whether the provider will do autosync.
     */
    private boolean mOneTimeSyncMode = false;

    public SyncStateCheckBoxPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        setWidgetLayoutResource(R.layout.preference_widget_sync_toggle);
        mAccount = null;
        mAuthority = null;
    }

    public SyncStateCheckBoxPreference(Context context, Account account, String authority) {
        super(context, null);
        mAccount = account;
        mAuthority = authority;
        setWidgetLayoutResource(R.layout.preference_widget_sync_toggle);
    }

    @Override
    public void onBindView(View view) {
        super.onBindView(view);
        final AnimatedImageView syncActiveView = (AnimatedImageView) view.findViewById(
                R.id.sync_active);
        final View syncFailedView = view.findViewById(R.id.sync_failed);

        final boolean activeVisible = mIsActive || mIsPending;
        syncActiveView.setVisibility(activeVisible ? View.VISIBLE : View.GONE);
        syncActiveView.setAnimating(mIsActive);

        final boolean failedVisible = mFailed && !activeVisible;
        syncFailedView.setVisibility(failedVisible ? View.VISIBLE : View.GONE);

        View checkBox = view.findViewById(android.R.id.checkbox);
        if (mOneTimeSyncMode) {
            checkBox.setVisibility(View.GONE);

            /*
             * Override the summary. Fill in the %1$s with the existing summary
             * (what ends up happening is the old summary is shown on the next
             * line).
             */
            TextView summary = (TextView) view.findViewById(android.R.id.summary);
            summary.setText(getContext().getString(R.string.sync_one_time_sync, getSummary()));
        } else {
            checkBox.setVisibility(View.VISIBLE);
        }
    }

    /**
     * Set whether the sync is active.
     * @param isActive whether or not the sync is active
     */
    public void setActive(boolean isActive) {
        mIsActive = isActive;
        notifyChanged();
    }

    /**
     * Set whether a sync is pending.
     * @param isPending whether or not the sync is pending
     */
    public void setPending(boolean isPending) {
        mIsPending = isPending;
        notifyChanged();
    }

    /**
     * Set whether the corresponding sync failed.
     * @param failed whether or not the sync failed
     */
    public void setFailed(boolean failed) {
        mFailed = failed;
        notifyChanged();
    }

    /**
     * Sets whether the preference is in one-time sync mode.
     */
    public void setOneTimeSyncMode(boolean oneTimeSyncMode) {
        mOneTimeSyncMode = oneTimeSyncMode;
        notifyChanged();
    }

    /**
     * Gets whether the preference is in one-time sync mode.
     */
    public boolean isOneTimeSyncMode() {
        return mOneTimeSyncMode;
    }

    @Override
    protected void onClick() {
        // When we're in one-time sync mode, we don't want a click to change the
        // checkbox state
        if (!mOneTimeSyncMode) {
            super.onClick();
        }
    }

    public Account getAccount() {
        return mAccount;
    }

    public String getAuthority() {
        return mAuthority;
    }
}
