1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.documentsui.sorting;
18
19import android.annotation.IntDef;
20import android.os.Parcel;
21import android.os.Parcelable;
22import android.support.annotation.StringRes;
23import android.view.View;
24
25import java.lang.annotation.Retention;
26import java.lang.annotation.RetentionPolicy;
27
28/**
29 * A model class that describes a sort dimension and its sort state.
30 */
31public class SortDimension implements Parcelable {
32
33    /**
34     * This enum is defined as flag because it's also used to denote whether a column can be sorted
35     * in a certain direction.
36     */
37    @IntDef(flag = true, value = {
38            SORT_DIRECTION_NONE,
39            SORT_DIRECTION_ASCENDING,
40            SORT_DIRECTION_DESCENDING
41    })
42    @Retention(RetentionPolicy.SOURCE)
43    public @interface SortDirection {}
44    public static final int SORT_DIRECTION_NONE = 0;
45    public static final int SORT_DIRECTION_ASCENDING = 1;
46    public static final int SORT_DIRECTION_DESCENDING = 2;
47
48    @IntDef({
49            SORT_CAPABILITY_NONE,
50            SORT_CAPABILITY_BOTH_DIRECTION
51    })
52    @Retention(RetentionPolicy.SOURCE)
53    @interface SortCapability {}
54    public static final int SORT_CAPABILITY_NONE = 0;
55    public static final int SORT_CAPABILITY_BOTH_DIRECTION =
56            SORT_DIRECTION_ASCENDING | SORT_DIRECTION_DESCENDING;
57
58    @IntDef({
59            DATA_TYPE_STRING,
60            DATA_TYPE_NUMBER
61    })
62    @Retention(RetentionPolicy.SOURCE)
63    public @interface DataType {}
64    public static final int DATA_TYPE_STRING = 0;
65    public static final int DATA_TYPE_NUMBER = 1;
66
67    private final int mId;
68    private final @StringRes int mLabelId;
69    private final @DataType int mDataType;
70    private final @SortCapability int mSortCapability;
71    private final @SortDirection int mDefaultSortDirection;
72
73    @SortDirection int mSortDirection = SORT_DIRECTION_NONE;
74    int mVisibility;
75
76    private SortDimension(int id, @StringRes int labelId, @DataType int dataType,
77            @SortCapability int sortCapability, @SortDirection int defaultSortDirection) {
78        mId = id;
79        mLabelId = labelId;
80        mDataType = dataType;
81        mSortCapability = sortCapability;
82        mDefaultSortDirection = defaultSortDirection;
83    }
84
85    public int getId() {
86        return mId;
87    }
88
89    public @StringRes int getLabelId() {
90        return mLabelId;
91    }
92
93    public @DataType int getDataType() {
94        return mDataType;
95    }
96
97    public @SortCapability int getSortCapability() {
98        return mSortCapability;
99    }
100
101    public @SortDirection int getDefaultSortDirection() {
102        return mDefaultSortDirection;
103    }
104
105    public @SortDirection int getNextDirection() {
106        @SortDimension.SortDirection int alternativeDirection =
107                (mDefaultSortDirection == SortDimension.SORT_DIRECTION_ASCENDING)
108                        ? SortDimension.SORT_DIRECTION_DESCENDING
109                        : SortDimension.SORT_DIRECTION_ASCENDING;
110        @SortDimension.SortDirection int direction =
111                (mSortDirection == mDefaultSortDirection)
112                        ? alternativeDirection
113                        : mDefaultSortDirection;
114
115        return direction;
116    }
117
118    public @SortDirection int getSortDirection() {
119        return mSortDirection;
120    }
121
122    public int getVisibility() {
123        return mVisibility;
124    }
125
126    @Override
127    public int hashCode() {
128        return mId;
129    }
130
131    @Override
132    public boolean equals(Object o) {
133        if (o == null || !(o instanceof SortDimension)) {
134            return false;
135        }
136
137        if (this == o) {
138            return true;
139        }
140
141        SortDimension other = (SortDimension) o;
142
143        return mId == other.mId
144                && mLabelId == other.mLabelId
145                && mDataType == other.mDataType
146                && mSortCapability == other.mSortCapability
147                && mDefaultSortDirection == other.mDefaultSortDirection
148                && mSortDirection == other.mSortDirection
149                && mVisibility == other.mVisibility;
150    }
151
152    @Override
153    public String toString() {
154        return new StringBuilder().append("SortDimension{")
155                .append("id=").append(mId)
156                .append(", labelId=").append(mLabelId)
157                .append(", dataType=").append(mDataType)
158                .append(", sortCapability=").append(mSortCapability)
159                .append(", defaultSortDirection=").append(mDefaultSortDirection)
160                .append(", sortDirection=").append(mSortDirection)
161                .append(", visibility=").append(mVisibility)
162                .append("}")
163                .toString();
164    }
165
166    @Override
167    public int describeContents() {
168        return 0;
169    }
170
171    @Override
172    public void writeToParcel(Parcel out, int flag) {
173        out.writeInt(mId);
174        out.writeInt(mLabelId);
175        out.writeInt(mDataType);
176        out.writeInt(mSortCapability);
177        out.writeInt(mDefaultSortDirection);
178        out.writeInt(mSortDirection);
179        out.writeInt(mVisibility);
180    }
181
182    public static Parcelable.Creator<SortDimension> CREATOR =
183            new Parcelable.Creator<SortDimension>() {
184
185        @Override
186        public SortDimension createFromParcel(Parcel in) {
187            int id = in.readInt();
188            @StringRes int labelId = in.readInt();
189            @DataType  int dataType = in.readInt();
190            int sortCapability = in.readInt();
191            int defaultSortDirection = in.readInt();
192
193            SortDimension column =
194                    new SortDimension(id, labelId, dataType, sortCapability, defaultSortDirection);
195
196            column.mSortDirection = in.readInt();
197            column.mVisibility = in.readInt();
198
199            return column;
200        }
201
202        @Override
203        public SortDimension[] newArray(int size) {
204            return new SortDimension[size];
205        }
206    };
207
208    static class Builder {
209        private int mId;
210        private @StringRes int mLabelId;
211        private @DataType int mDataType = DATA_TYPE_STRING;
212        private @SortCapability int mSortCapability = SORT_CAPABILITY_BOTH_DIRECTION;
213        private @SortDirection int mDefaultSortDirection = SORT_DIRECTION_ASCENDING;
214        private int mVisibility = View.VISIBLE;
215
216        Builder withId(int id) {
217            mId = id;
218            return this;
219        }
220
221        Builder withLabelId(@StringRes int labelId) {
222            mLabelId = labelId;
223            return this;
224        }
225
226        Builder withDataType(@DataType int dataType) {
227            mDataType = dataType;
228            return this;
229        }
230
231        Builder withSortCapability(@SortCapability int sortCapability) {
232            mSortCapability = sortCapability;
233            return this;
234        }
235
236        Builder withVisibility(int visibility) {
237            mVisibility = visibility;
238            return this;
239        }
240
241        Builder withDefaultSortDirection(@SortDirection int defaultSortDirection) {
242            mDefaultSortDirection = defaultSortDirection;
243            return this;
244        }
245
246        SortDimension build() {
247            if (mLabelId == 0) {
248                throw new IllegalStateException("Must set labelId.");
249            }
250
251            SortDimension dimension = new SortDimension(
252                    mId, mLabelId, mDataType, mSortCapability, mDefaultSortDirection);
253            dimension.mVisibility = mVisibility;
254            return dimension;
255        }
256    }
257}
258