1/*
2 * Copyright (C) 2015 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.tv.data;
18
19import android.support.annotation.NonNull;
20import android.view.KeyEvent;
21
22/**
23 * A convenience class to handle channel number.
24 */
25public final class ChannelNumber implements Comparable<ChannelNumber> {
26    public static final String PRIMARY_CHANNEL_DELIMITER = "-";
27    public static final String[] CHANNEL_DELIMITERS = {"-", ".", " "};
28
29    private static final int[] CHANNEL_DELIMITER_KEYCODES = {
30        KeyEvent.KEYCODE_MINUS, KeyEvent.KEYCODE_NUMPAD_SUBTRACT, KeyEvent.KEYCODE_PERIOD,
31        KeyEvent.KEYCODE_NUMPAD_DOT, KeyEvent.KEYCODE_SPACE
32    };
33
34    public String majorNumber;
35    public boolean hasDelimiter;
36    public String minorNumber;
37
38    public ChannelNumber() {
39        reset();
40    }
41
42    public ChannelNumber(String major, boolean hasDelimiter, String minor) {
43        setChannelNumber(major, hasDelimiter, minor);
44    }
45
46    public void reset() {
47        setChannelNumber("", false, "");
48    }
49
50    public void setChannelNumber(String majorNumber, boolean hasDelimiter, String minorNumber) {
51        this.majorNumber = majorNumber;
52        this.hasDelimiter = hasDelimiter;
53        this.minorNumber = minorNumber;
54    }
55
56    @Override
57    public String toString() {
58        if (hasDelimiter) {
59            return majorNumber + PRIMARY_CHANNEL_DELIMITER + minorNumber;
60        }
61        return majorNumber;
62    }
63
64    @Override
65    public int compareTo(@NonNull ChannelNumber another) {
66        int major = Integer.parseInt(majorNumber);
67        int minor = hasDelimiter ? Integer.parseInt(minorNumber) : 0;
68
69        int opponentMajor = Integer.parseInt(another.majorNumber);
70        int opponentMinor = another.hasDelimiter
71                ? Integer.parseInt(another.minorNumber) : 0;
72        if (major == opponentMajor) {
73            return minor - opponentMinor;
74        }
75        return major - opponentMajor;
76    }
77
78    public static boolean isChannelNumberDelimiterKey(int keyCode) {
79        for (int delimiterKeyCode : CHANNEL_DELIMITER_KEYCODES) {
80            if (delimiterKeyCode == keyCode) {
81                return true;
82            }
83        }
84        return false;
85    }
86
87    public static ChannelNumber parseChannelNumber(String number) {
88        if (number == null) {
89            return null;
90        }
91        ChannelNumber ret = new ChannelNumber();
92        int indexOfDelimiter = -1;
93        for (String delimiter : CHANNEL_DELIMITERS) {
94            indexOfDelimiter = number.indexOf(delimiter);
95            if (indexOfDelimiter >= 0) {
96                break;
97            }
98        }
99        if (indexOfDelimiter == 0 || indexOfDelimiter == number.length() - 1) {
100            return null;
101        }
102        if (indexOfDelimiter < 0) {
103            ret.majorNumber = number;
104            if (!isInteger(ret.majorNumber)) {
105                return null;
106            }
107        } else {
108            ret.hasDelimiter = true;
109            ret.majorNumber = number.substring(0, indexOfDelimiter);
110            ret.minorNumber = number.substring(indexOfDelimiter + 1);
111            if (!isInteger(ret.majorNumber) || !isInteger(ret.minorNumber)) {
112                return null;
113            }
114        }
115        return ret;
116    }
117
118    public static int compare(String lhs, String rhs) {
119        ChannelNumber lhsNumber = parseChannelNumber(lhs);
120        ChannelNumber rhsNumber = parseChannelNumber(rhs);
121        if (lhsNumber == null && rhsNumber == null) {
122            return 0;
123        } else if (lhsNumber == null /* && rhsNumber != null */) {
124            return -1;
125        } else if (lhsNumber != null && rhsNumber == null) {
126            return 1;
127        }
128        return lhsNumber.compareTo(rhsNumber);
129    }
130
131    public static boolean isInteger(String string) {
132        try {
133            Integer.parseInt(string);
134        } catch(NumberFormatException e) {
135            return false;
136        } catch(NullPointerException e) {
137            return false;
138        }
139        return true;
140    }
141}
142