/*
 * Copyright (C) 2019 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.service.controls;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.drawable.Icon;
import android.os.Parcel;
import android.os.Parcelable;
import android.service.controls.actions.ControlAction;
import android.service.controls.templates.ControlTemplate;
import android.service.controls.templates.ControlTemplateWrapper;
import android.util.Log;

import com.android.internal.util.Preconditions;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Represents a physical object that can be represented by a {@link ControlTemplate} and whose
 * properties may be modified through a {@link ControlAction}.
 *
 * The information is provided by a {@link ControlsProviderService} and represents static
 * information (not current status) about the device.
 * <p>
 * Each control needs a unique (per provider) identifier that is persistent across reboots of the
 * system.
 * <p>
 * Each {@link Control} will have a name, a subtitle and will optionally belong to a structure
 * and zone. Some of these values are defined by the user and/or the {@link ControlsProviderService}
 * and will be used to display the control as well as group them for management.
 * <p>
 * Each object will have an associated {@link DeviceTypes.DeviceType}. This will determine the icons and colors
 * used to display it.
 * <p>
 * An {@link Intent} linking to the provider Activity that expands on this {@link Control} and
 * allows for further actions should be provided.
 */
public final class Control implements Parcelable {
    private static final String TAG = "Control";

    private static final int NUM_STATUS = 5;
    /**
     * @hide
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({
            STATUS_UNKNOWN,
            STATUS_OK,
            STATUS_NOT_FOUND,
            STATUS_ERROR,
            STATUS_DISABLED,
    })
    public @interface Status {};

    /**
     * Reserved for use with the {@link StatelessBuilder}, and while loading. When state is
     * requested via {@link ControlsProviderService#createPublisherFor}, use other status codes
     * to indicate the proper device state.
     */
    public static final int STATUS_UNKNOWN = 0;

    /**
     * Used to indicate that the state of the device was successfully retrieved. This includes
     * all scenarios where the device may have a warning for the user, such as "Lock jammed",
     * or "Vacuum stuck". Any information for the user should be set through
     * {@link StatefulBuilder#setStatusText}.
     */
    public static final int STATUS_OK = 1;

    /**
     * The device corresponding to the {@link Control} cannot be found or was removed. The user
     * will be alerted and directed to the application to resolve.
     */
    public static final int STATUS_NOT_FOUND = 2;

    /**
     * Used to indicate that there was a temporary error while loading the device state. A default
     * error message will be displayed in place of any custom text that was set through
     * {@link StatefulBuilder#setStatusText}.
     */
    public static final int STATUS_ERROR = 3;

    /**
     * The {@link Control} is currently disabled.  A default error message will be displayed in
     * place of any custom text that was set through {@link StatefulBuilder#setStatusText}.
     */
    public static final int STATUS_DISABLED = 4;

    private final @NonNull String mControlId;
    private final @DeviceTypes.DeviceType int mDeviceType;
    private final @NonNull CharSequence mTitle;
    private final @NonNull CharSequence mSubtitle;
    private final @Nullable CharSequence mStructure;
    private final @Nullable CharSequence mZone;
    private final @NonNull PendingIntent mAppIntent;

    private final @Nullable Icon mCustomIcon;
    private final @Nullable ColorStateList mCustomColor;

    private final @Status int mStatus;
    private final @NonNull ControlTemplate mControlTemplate;
    private final @NonNull CharSequence mStatusText;

    /**
     * @param controlId the unique persistent identifier for this object.
     * @param deviceType the type of device for this control. This will determine icons and colors.
     * @param title the user facing name of this control (e.g. "Bedroom thermostat").
     * @param subtitle a user facing subtitle with extra information about this control
     * @param structure a user facing name for the structure containing the device associated with
     *                  this control.
     * @param zone
     * @param appIntent a {@link PendingIntent} linking to a page to interact with the
     *                  corresponding device.
     * @param customIcon
     * @param customColor
     * @param status
     * @param controlTemplate
     * @param statusText
     */
    Control(@NonNull String controlId,
            @DeviceTypes.DeviceType int deviceType,
            @NonNull CharSequence title,
            @NonNull CharSequence subtitle,
            @Nullable CharSequence structure,
            @Nullable CharSequence zone,
            @NonNull PendingIntent appIntent,
            @Nullable Icon customIcon,
            @Nullable ColorStateList customColor,
            @Status int status,
            @NonNull ControlTemplate controlTemplate,
            @NonNull CharSequence statusText) {
        Preconditions.checkNotNull(controlId);
        Preconditions.checkNotNull(title);
        Preconditions.checkNotNull(subtitle);
        Preconditions.checkNotNull(appIntent);
        Preconditions.checkNotNull(controlTemplate);
        Preconditions.checkNotNull(statusText);
        mControlId = controlId;
        if (!DeviceTypes.validDeviceType(deviceType)) {
            Log.e(TAG, "Invalid device type:" + deviceType);
            mDeviceType = DeviceTypes.TYPE_UNKNOWN;
        } else {
            mDeviceType = deviceType;
        }
        mTitle = title;
        mSubtitle = subtitle;
        mStructure = structure;
        mZone = zone;
        mAppIntent = appIntent;

        mCustomColor = customColor;
        mCustomIcon = customIcon;

        if (status < 0 || status >= NUM_STATUS) {
            mStatus = STATUS_UNKNOWN;
            Log.e(TAG, "Status unknown:" + status);
        } else {
            mStatus = status;
        }
        mControlTemplate = controlTemplate;
        mStatusText = statusText;
    }

    /**
     * @param in
     * @hide
     */
    Control(Parcel in) {
        mControlId = in.readString();
        mDeviceType = in.readInt();
        mTitle = in.readCharSequence();
        mSubtitle = in.readCharSequence();
        if (in.readByte() == (byte) 1) {
            mStructure = in.readCharSequence();
        } else {
            mStructure = null;
        }
        if (in.readByte() == (byte) 1) {
            mZone = in.readCharSequence();
        } else {
            mZone = null;
        }
        mAppIntent = PendingIntent.CREATOR.createFromParcel(in);

        if (in.readByte() == (byte) 1) {
            mCustomIcon = Icon.CREATOR.createFromParcel(in);
        } else {
            mCustomIcon = null;
        }

        if (in.readByte() == (byte) 1) {
            mCustomColor = ColorStateList.CREATOR.createFromParcel(in);
        } else {
            mCustomColor = null;
        }

        mStatus = in.readInt();
        ControlTemplateWrapper wrapper = ControlTemplateWrapper.CREATOR.createFromParcel(in);
        mControlTemplate = wrapper.getWrappedTemplate();
        mStatusText = in.readCharSequence();
    }

    /**
     * @return the identifier for the {@link Control}
     */
    @NonNull
    public String getControlId() {
        return mControlId;
    }


    /**
     * @return type of device represented by this {@link Control}, used to determine the default
     *         icon and color
     */
    @DeviceTypes.DeviceType
    public int getDeviceType() {
        return mDeviceType;
    }

    /**
     * @return the user facing name of the {@link Control}
     */
    @NonNull
    public CharSequence getTitle() {
        return mTitle;
    }

    /**
     * @return additional information about the {@link Control}, to appear underneath the title
     */
    @NonNull
    public CharSequence getSubtitle() {
        return mSubtitle;
    }

    /**
     * Optional top-level group to help define the {@link Control}'s location, visible to the user.
     * If not present, the application name will be used as the top-level group. A structure
     * contains zones which contains controls.
     *
     * @return name of the structure containing the control
     */
    @Nullable
    public CharSequence getStructure() {
        return mStructure;
    }

    /**
     * Optional group name to help define the {@link Control}'s location within a structure,
     * visible to the user. A structure contains zones which contains controls.
     *
     * @return name of the zone containing the control
     */
    @Nullable
    public CharSequence getZone() {
        return mZone;
    }

    /**
     * @return a {@link PendingIntent} linking to an Activity for the {@link Control}
     */
    @NonNull
    public PendingIntent getAppIntent() {
        return mAppIntent;
    }

    /**
     * Optional icon to be shown with the {@link Control}. It is highly recommended
     * to let the system default the icon unless the default icon is not suitable.
     *
     * @return icon to show
     */
    @Nullable
    public Icon getCustomIcon() {
        return mCustomIcon;
    }

    /**
     * Optional color to be shown with the {@link Control}. It is highly recommended
     * to let the system default the color unless the default is not suitable for the
     * application.
     *
     * @return background color to use
     */
    @Nullable
    public ColorStateList getCustomColor() {
        return mCustomColor;
    }

    /**
     * @return status of the {@link Control}, used to convey information about the attempt to
     *         fetch the current state
     */
    @Status
    public int getStatus() {
        return mStatus;
    }

    /**
     * @return instance of {@link ControlTemplate}, that defines how the {@link Control} will
     *         behave and what interactions are available to the user
     */
    @NonNull
    public ControlTemplate getControlTemplate() {
        return mControlTemplate;
    }

    /**
     * @return user-facing text description of the {@link Control}'s status, describing its current
     *         state
     */
    @NonNull
    public CharSequence getStatusText() {
        return mStatusText;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeString(mControlId);
        dest.writeInt(mDeviceType);
        dest.writeCharSequence(mTitle);
        dest.writeCharSequence(mSubtitle);
        if (mStructure != null) {
            dest.writeByte((byte) 1);
            dest.writeCharSequence(mStructure);
        } else {
            dest.writeByte((byte) 0);
        }
        if (mZone != null) {
            dest.writeByte((byte) 1);
            dest.writeCharSequence(mZone);
        } else {
            dest.writeByte((byte) 0);
        }
        mAppIntent.writeToParcel(dest, flags);
        if (mCustomIcon != null) {
            dest.writeByte((byte) 1);
            mCustomIcon.writeToParcel(dest, flags);
        } else {
            dest.writeByte((byte) 0);
        }
        if (mCustomColor != null) {
            dest.writeByte((byte) 1);
            mCustomColor.writeToParcel(dest, flags);
        } else {
            dest.writeByte((byte) 0);
        }

        dest.writeInt(mStatus);
        new ControlTemplateWrapper(mControlTemplate).writeToParcel(dest, flags);
        dest.writeCharSequence(mStatusText);
    }

    public static final @NonNull Creator<Control> CREATOR = new Creator<Control>() {
        @Override
        public Control createFromParcel(@NonNull Parcel source) {
            return new Control(source);
        }

        @Override
        public Control[] newArray(int size) {
            return new Control[size];
        }
    };

    /**
     * Builder class for {@link Control}.
     *
     * This class facilitates the creation of {@link Control} with no state. Must be used to
     * provide controls for {@link ControlsProviderService#createPublisherForAllAvailable} and
     * {@link ControlsProviderService#createPublisherForSuggested}.
     *
     * It provides the following defaults for non-optional parameters:
     * <ul>
     *     <li> Device type: {@link DeviceTypes#TYPE_UNKNOWN}
     *     <li> Title: {@code ""}
     *     <li> Subtitle: {@code ""}
     * </ul>
     * This fixes the values relating to state of the {@link Control} as required by
     * {@link ControlsProviderService#createPublisherForAllAvailable}:
     * <ul>
     *     <li> Status: {@link Status#STATUS_UNKNOWN}
     *     <li> Control template: {@link ControlTemplate#getNoTemplateObject}
     *     <li> Status text: {@code ""}
     * </ul>
     */
    @SuppressLint("MutableBareField")
    public static final class StatelessBuilder {
        private static final String TAG = "StatelessBuilder";
        private @NonNull String mControlId;
        private @DeviceTypes.DeviceType int mDeviceType = DeviceTypes.TYPE_UNKNOWN;
        private @NonNull CharSequence mTitle = "";
        private @NonNull CharSequence mSubtitle = "";
        private @Nullable CharSequence mStructure;
        private @Nullable CharSequence mZone;
        private @NonNull PendingIntent mAppIntent;
        private @Nullable Icon mCustomIcon;
        private @Nullable ColorStateList mCustomColor;

        /**
         * @param controlId the identifier for the {@link Control}
         * @param appIntent the pending intent linking to the device Activity
         */
        public StatelessBuilder(@NonNull String controlId,
                @NonNull PendingIntent appIntent) {
            Preconditions.checkNotNull(controlId);
            Preconditions.checkNotNull(appIntent);
            mControlId = controlId;
            mAppIntent = appIntent;
        }

        /**
         * Creates a {@link StatelessBuilder} using an existing {@link Control} as a base.
         *
         * @param control base for the builder.
         */
        public StatelessBuilder(@NonNull Control control) {
            Preconditions.checkNotNull(control);
            mControlId = control.mControlId;
            mDeviceType = control.mDeviceType;
            mTitle = control.mTitle;
            mSubtitle = control.mSubtitle;
            mStructure = control.mStructure;
            mZone = control.mZone;
            mAppIntent = control.mAppIntent;
            mCustomIcon = control.mCustomIcon;
            mCustomColor = control.mCustomColor;
        }

        /**
         * @param controlId the identifier for the {@link Control}
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setControlId(@NonNull String controlId) {
            Preconditions.checkNotNull(controlId);
            mControlId = controlId;
            return this;
        }

        /**
         * @param deviceType type of device represented by this {@link Control}, used to
         *                   determine the default icon and color
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setDeviceType(@DeviceTypes.DeviceType int deviceType) {
            if (!DeviceTypes.validDeviceType(deviceType)) {
                Log.e(TAG, "Invalid device type:" + deviceType);
                mDeviceType = DeviceTypes.TYPE_UNKNOWN;
            } else {
                mDeviceType = deviceType;
            }
            return this;
        }

        /**
         * @param title the user facing name of the {@link Control}
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setTitle(@NonNull CharSequence title) {
            Preconditions.checkNotNull(title);
            mTitle = title;
            return this;
        }

        /**
         * @param subtitle additional information about the {@link Control}, to appear underneath
         *                 the title
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setSubtitle(@NonNull CharSequence subtitle) {
            Preconditions.checkNotNull(subtitle);
            mSubtitle = subtitle;
            return this;
        }

        /**
         * Optional top-level group to help define the {@link Control}'s location, visible to the
         * user. If not present, the application name will be used as the top-level group. A
         * structure contains zones which contains controls.
         *
         * @param structure name of the structure containing the control
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setStructure(@Nullable CharSequence structure) {
            mStructure = structure;
            return this;
        }

        /**
         * Optional group name to help define the {@link Control}'s location within a structure,
         * visible to the user. A structure contains zones which contains controls.
         *
         * @param zone name of the zone containing the control
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setZone(@Nullable CharSequence zone) {
            mZone = zone;
            return this;
        }

        /**
         * @param appIntent a {@link PendingIntent} linking to an Activity for the {@link Control}
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setAppIntent(@NonNull PendingIntent appIntent) {
            Preconditions.checkNotNull(appIntent);
            mAppIntent = appIntent;
            return this;
        }

        /**
         * Optional icon to be shown with the {@link Control}. It is highly recommended
         * to let the system default the icon unless the default icon is not suitable.
         *
         * @param customIcon icon to show
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setCustomIcon(@Nullable Icon customIcon) {
            mCustomIcon = customIcon;
            return this;
        }

        /**
         * Optional color to be shown with the {@link Control}. It is highly recommended
         * to let the system default the color unless the default is not suitable for the
         * application.
         *
         * @param customColor background color to use
         * @return {@code this}
         */
        @NonNull
        public StatelessBuilder setCustomColor(@Nullable ColorStateList customColor) {
            mCustomColor = customColor;
            return this;
        }

        /**
         * @return a valid {@link Control}
         */
        @NonNull
        public Control build() {
            return new Control(mControlId,
                    mDeviceType,
                    mTitle,
                    mSubtitle,
                    mStructure,
                    mZone,
                    mAppIntent,
                    mCustomIcon,
                    mCustomColor,
                    STATUS_UNKNOWN,
                    ControlTemplate.NO_TEMPLATE,
                    "");
        }
    }

    /**
     * Builder class for {@link Control} that contains state information.
     *
     * State information is passed through an instance of a {@link ControlTemplate} and will
     * determine how the user can interact with the {@link Control}. User interactions will
     * be sent through the method call {@link ControlsProviderService#performControlAction}
     * with an instance of {@link ControlAction} to convey any potential new value.
     *
     * Must be used to provide controls for {@link ControlsProviderService#createPublisherFor}.
     *
     * It provides the following defaults for non-optional parameters:
     * <ul>
     *     <li> Device type: {@link DeviceTypes#TYPE_UNKNOWN}
     *     <li> Title: {@code ""}
     *     <li> Subtitle: {@code ""}
     *     <li> Status: {@link Status#STATUS_UNKNOWN}
     *     <li> Control template: {@link ControlTemplate#getNoTemplateObject}
     *     <li> Status text: {@code ""}
     * </ul>
     */
    public static final class StatefulBuilder {
        private static final String TAG = "StatefulBuilder";
        private @NonNull String mControlId;
        private @DeviceTypes.DeviceType int mDeviceType = DeviceTypes.TYPE_UNKNOWN;
        private @NonNull CharSequence mTitle = "";
        private @NonNull CharSequence mSubtitle = "";
        private @Nullable CharSequence mStructure;
        private @Nullable CharSequence mZone;
        private @NonNull PendingIntent mAppIntent;
        private @Nullable Icon mCustomIcon;
        private @Nullable ColorStateList mCustomColor;
        private @Status int mStatus = STATUS_UNKNOWN;
        private @NonNull ControlTemplate mControlTemplate = ControlTemplate.NO_TEMPLATE;
        private @NonNull CharSequence mStatusText = "";

        /**
         * @param controlId the identifier for the {@link Control}.
         * @param appIntent the pending intent linking to the device Activity.
         */
        public StatefulBuilder(@NonNull String controlId,
                @NonNull PendingIntent appIntent) {
            Preconditions.checkNotNull(controlId);
            Preconditions.checkNotNull(appIntent);
            mControlId = controlId;
            mAppIntent = appIntent;
        }

        /**
         * Creates a {@link StatelessBuilder} using an existing {@link Control} as a base.
         *
         * @param control base for the builder.
         */
        public StatefulBuilder(@NonNull Control control) {
            Preconditions.checkNotNull(control);
            mControlId = control.mControlId;
            mDeviceType = control.mDeviceType;
            mTitle = control.mTitle;
            mSubtitle = control.mSubtitle;
            mStructure = control.mStructure;
            mZone = control.mZone;
            mAppIntent = control.mAppIntent;
            mCustomIcon = control.mCustomIcon;
            mCustomColor = control.mCustomColor;
            mStatus = control.mStatus;
            mControlTemplate = control.mControlTemplate;
            mStatusText = control.mStatusText;
        }

        /**
         * @param controlId the identifier for the {@link Control}.
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setControlId(@NonNull String controlId) {
            Preconditions.checkNotNull(controlId);
            mControlId = controlId;
            return this;
        }

        /**
         * @param deviceType type of device represented by this {@link Control}, used to
         *                   determine the default icon and color
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setDeviceType(@DeviceTypes.DeviceType int deviceType) {
            if (!DeviceTypes.validDeviceType(deviceType)) {
                Log.e(TAG, "Invalid device type:" + deviceType);
                mDeviceType = DeviceTypes.TYPE_UNKNOWN;
            } else {
                mDeviceType = deviceType;
            }
            return this;
        }

        /**
         * @param title the user facing name of the {@link Control}
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setTitle(@NonNull CharSequence title) {
            Preconditions.checkNotNull(title);
            mTitle = title;
            return this;
        }

        /**
         * @param subtitle additional information about the {@link Control}, to appear underneath
         *                 the title
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setSubtitle(@NonNull CharSequence subtitle) {
            Preconditions.checkNotNull(subtitle);
            mSubtitle = subtitle;
            return this;
        }

        /**
         * Optional top-level group to help define the {@link Control}'s location, visible to the
         * user. If not present, the application name will be used as the top-level group. A
         * structure contains zones which contains controls.
         *
         * @param structure name of the structure containing the control
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setStructure(@Nullable CharSequence structure) {
            mStructure = structure;
            return this;
        }

        /**
         * Optional group name to help define the {@link Control}'s location within a structure,
         * visible to the user. A structure contains zones which contains controls.
         *
         * @param zone name of the zone containing the control
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setZone(@Nullable CharSequence zone) {
            mZone = zone;
            return this;
        }

        /**
         * @param appIntent a {@link PendingIntent} linking to an Activity for the {@link Control}
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setAppIntent(@NonNull PendingIntent appIntent) {
            Preconditions.checkNotNull(appIntent);
            mAppIntent = appIntent;
            return this;
        }

        /**
         * Optional icon to be shown with the {@link Control}. It is highly recommended
         * to let the system default the icon unless the default icon is not suitable.
         *
         * @param customIcon icon to show
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setCustomIcon(@Nullable Icon customIcon) {
            mCustomIcon = customIcon;
            return this;
        }

        /**
         * Optional color to be shown with the {@link Control}. It is highly recommended
         * to let the system default the color unless the default is not suitable for the
         * application.
         *
         * @param customColor background color to use
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setCustomColor(@Nullable ColorStateList customColor) {
            mCustomColor = customColor;
            return this;
        }

        /**
         * @param status status of the {@link Control}, used to convey information about the
         *               attempt to fetch the current state
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setStatus(@Status int status) {
            if (status < 0 || status >= NUM_STATUS) {
                mStatus = STATUS_UNKNOWN;
                Log.e(TAG, "Status unknown:" + status);
            } else {
                mStatus = status;
            }
            return this;
        }

        /**
         * Set the {@link ControlTemplate} to define the primary user interaction
         *
         * Devices may support a variety of user interactions, and all interactions cannot be
         * represented with a single {@link ControlTemplate}. Therefore, the selected template
         * should be most closely aligned with what the expected primary device action will be.
         * Any secondary interactions can be done via the {@link #setAppIntent(PendingIntent)}.
         *
         * @param controlTemplate instance of {@link ControlTemplate}, that defines how the
         *                        {@link Control} will behave and what interactions are
         *                        available to the user
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setControlTemplate(@NonNull ControlTemplate controlTemplate) {
            Preconditions.checkNotNull(controlTemplate);
            mControlTemplate = controlTemplate;
            return this;
        }

        /**
         * @param statusText user-facing text description of the {@link Control}'s status,
         *                   describing its current state
         * @return {@code this}
         */
        @NonNull
        public StatefulBuilder setStatusText(@NonNull CharSequence statusText) {
            Preconditions.checkNotNull(statusText);
            mStatusText = statusText;
            return this;
        }

        /**
         * @return a valid {@link Control}
         */
        @NonNull
        public Control build() {
            return new Control(mControlId,
                    mDeviceType,
                    mTitle,
                    mSubtitle,
                    mStructure,
                    mZone,
                    mAppIntent,
                    mCustomIcon,
                    mCustomColor,
                    mStatus,
                    mControlTemplate,
                    mStatusText);
        }
    }
}
