/*
 * Copyright (C) 2018 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.systemui.statusbar;

import static com.android.systemui.statusbar.policy.DarkIconDispatcher.getTint;
import static com.android.systemui.statusbar.policy.DarkIconDispatcher.isInArea;

import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;

import com.android.keyguard.AlphaOptimizedLinearLayout;
import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;

/**
 * Start small: StatusBarWifiView will be able to layout from a WifiIconState
 */
public class StatusBarWifiView extends AlphaOptimizedLinearLayout implements DarkReceiver,
        StatusIconDisplayable {
    private static final String TAG = "StatusBarWifiView";

    private ImageView mWifiIcon;
    private ImageView mIn;
    private ImageView mOut;
    private View mInoutContainer;
    private View mSignalSpacer;
    private View mAirplaneSpacer;
    private WifiIconState mState;
    private String mSlot;
    private float mDarkIntensity = 0;

    private ContextThemeWrapper mDarkContext;
    private ContextThemeWrapper mLightContext;

    public static StatusBarWifiView fromContext(Context context) {
        LayoutInflater inflater = LayoutInflater.from(context);
        return (StatusBarWifiView) inflater.inflate(R.layout.status_bar_wifi_group, null);
    }

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

    public StatusBarWifiView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public StatusBarWifiView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public StatusBarWifiView(Context context, AttributeSet attrs, int defStyleAttr,
            int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        init();
    }

    public void setSlot(String slot) {
        mSlot = slot;
    }

    @Override
    public void setStaticDrawableColor(int color) {
        ColorStateList list = ColorStateList.valueOf(color);
        mWifiIcon.setImageTintList(list);
        mIn.setImageTintList(list);
        mOut.setImageTintList(list);
    }

    @Override
    public String getSlot() {
        return mSlot;
    }

    @Override
    public boolean isIconVisible() {
        return mState != null && mState.visible;
    }

    private void init() {
        int dualToneLightTheme = Utils.getThemeAttr(mContext, R.attr.lightIconTheme);
        int dualToneDarkTheme = Utils.getThemeAttr(mContext, R.attr.darkIconTheme);
        mLightContext = new ContextThemeWrapper(mContext, dualToneLightTheme);
        mDarkContext = new ContextThemeWrapper(mContext, dualToneDarkTheme);

        mWifiIcon = findViewById(R.id.wifi_signal);
        mIn = findViewById(R.id.wifi_in);
        mOut = findViewById(R.id.wifi_out);
        mSignalSpacer = findViewById(R.id.wifi_signal_spacer);
        mAirplaneSpacer = findViewById(R.id.wifi_airplane_spacer);
        mInoutContainer = findViewById(R.id.inout_container);
    }

    public void applyWifiState(WifiIconState state) {
        if (state == null) {
            setVisibility(View.GONE);
            mState = null;
            return;
        }

        if (mState == null) {
            mState = state;
            initViewState();
        }

        if (!mState.equals(state)) {
            updateState(state);
        }
    }

    private void updateState(WifiIconState state) {
        if (mState.resId != state.resId && state.resId >= 0) {
            NeutralGoodDrawable drawable = NeutralGoodDrawable
                    .create(mLightContext, mDarkContext, state.resId);
            drawable.setDarkIntensity(mDarkIntensity);
            mWifiIcon.setImageDrawable(drawable);
        }

        mIn.setVisibility(state.activityIn ? View.VISIBLE : View.GONE);
        mOut.setVisibility(state.activityOut ? View.VISIBLE : View.GONE);
        mInoutContainer.setVisibility(
                (state.activityIn || state.activityOut) ? View.VISIBLE : View.GONE);
        mAirplaneSpacer.setVisibility(state.airplaneSpacerVisible ? View.VISIBLE : View.GONE);
        mSignalSpacer.setVisibility(state.signalSpacerVisible ? View.VISIBLE : View.GONE);
        if (mState.visible != state.visible) {
            setVisibility(state.visible ? View.VISIBLE : View.GONE);
        }

        mState = state;
    }

    private void initViewState() {
        if (mState.resId >= 0) {
            NeutralGoodDrawable drawable = NeutralGoodDrawable.create(
                    mLightContext, mDarkContext, mState.resId);
            drawable.setDarkIntensity(mDarkIntensity);
            mWifiIcon.setImageDrawable(drawable);
        }

        mIn.setVisibility(mState.activityIn ? View.VISIBLE : View.GONE);
        mOut.setVisibility(mState.activityOut ? View.VISIBLE : View.GONE);
        mInoutContainer.setVisibility(
                (mState.activityIn || mState.activityOut) ? View.VISIBLE : View.GONE);
        mAirplaneSpacer.setVisibility(mState.airplaneSpacerVisible ? View.VISIBLE : View.GONE);
        mSignalSpacer.setVisibility(mState.signalSpacerVisible ? View.VISIBLE : View.GONE);
        setVisibility(mState.visible ? View.VISIBLE : View.GONE);
    }

    @Override
    public void onDarkChanged(Rect area, float darkIntensity, int tint) {
        if (!isInArea(area, this)) {
            return;
        }
        mDarkIntensity = darkIntensity;
        Drawable d = mWifiIcon.getDrawable();
        if (d instanceof NeutralGoodDrawable) {
            ((NeutralGoodDrawable)d).setDarkIntensity(darkIntensity);
        }
        mIn.setImageTintList(ColorStateList.valueOf(getTint(area, this, tint)));
        mOut.setImageTintList(ColorStateList.valueOf(getTint(area, this, tint)));
    }


    @Override
    public String toString() {
        return "StatusBarWifiView(slot=" + mSlot + " state=" + mState + ")";
    }
}
