1/*
2 * Copyright (C) 2008 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.hierarchyviewer.scene;
18
19import java.awt.Image;
20import java.util.ArrayList;
21import java.util.HashMap;
22import java.util.List;
23import java.util.Map;
24import java.util.regex.Pattern;
25
26public class ViewNode {
27    public String id;
28    public String name;
29
30    public List<Property> properties = new ArrayList<Property>();
31    public Map<String, Property> namedProperties = new HashMap<String, Property>();
32
33    public ViewNode parent;
34    public List<ViewNode> children = new ArrayList<ViewNode>();
35
36    public Image image;
37
38    public int left;
39    public int top;
40    public int width;
41    public int height;
42    public int scrollX;
43    public int scrollY;
44    public int paddingLeft;
45    public int paddingRight;
46    public int paddingTop;
47    public int paddingBottom;
48    public int marginLeft;
49    public int marginRight;
50    public int marginTop;
51    public int marginBottom;
52    public int baseline;
53    public boolean willNotDraw;
54    public boolean hasMargins;
55
56    boolean hasFocus;
57    int index;
58
59    public boolean decoded;
60    public boolean filtered;
61
62    private String shortName;
63    private StateListener listener;
64
65    void decode() {
66        id = namedProperties.get("mID").value;
67
68        left = getInt("mLeft", 0);
69        top = getInt("mTop", 0);
70        width = getInt("getWidth()", 0);
71        height = getInt("getHeight()", 0);
72        scrollX = getInt("mScrollX", 0);
73        scrollY = getInt("mScrollY", 0);
74        paddingLeft = getInt("mPaddingLeft", 0);
75        paddingRight = getInt("mPaddingRight", 0);
76        paddingTop = getInt("mPaddingTop", 0);
77        paddingBottom = getInt("mPaddingBottom", 0);
78        marginLeft = getInt("layout_leftMargin", Integer.MIN_VALUE);
79        marginRight = getInt("layout_rightMargin", Integer.MIN_VALUE);
80        marginTop = getInt("layout_topMargin", Integer.MIN_VALUE);
81        marginBottom = getInt("layout_bottomMargin", Integer.MIN_VALUE);
82        baseline = getInt("getBaseline()", 0);
83        willNotDraw = getBoolean("willNotDraw()", false);
84        hasFocus = getBoolean("hasFocus()", false);
85
86        hasMargins = marginLeft != Integer.MIN_VALUE &&
87                marginRight != Integer.MIN_VALUE &&
88                marginTop != Integer.MIN_VALUE &&
89                marginBottom != Integer.MIN_VALUE;
90
91        decoded = true;
92    }
93
94    private boolean getBoolean(String name, boolean defaultValue) {
95        Property p = namedProperties.get(name);
96        if (p != null) {
97            try {
98                return Boolean.parseBoolean(p.value);
99            } catch (NumberFormatException e) {
100                return defaultValue;
101            }
102        }
103        return defaultValue;
104    }
105
106    private int getInt(String name, int defaultValue) {
107        Property p = namedProperties.get(name);
108        if (p != null) {
109            try {
110                return Integer.parseInt(p.value);
111            } catch (NumberFormatException e) {
112                return defaultValue;
113            }
114        }
115        return defaultValue;
116    }
117
118    public void filter(Pattern pattern) {
119        if (pattern == null || pattern.pattern().length() == 0) {
120            filtered = false;
121        } else {
122            filtered = pattern.matcher(shortName).find() || pattern.matcher(id).find();
123        }
124        listener.nodeStateChanged(this);
125    }
126
127    void computeIndex() {
128        index = parent == null ? 0 : parent.children.indexOf(this);
129        listener.nodeIndexChanged(this);
130    }
131
132    void setShortName(String shortName) {
133        this.shortName = shortName;
134    }
135
136    void setStateListener(StateListener listener) {
137        this.listener = listener;
138    }
139
140    @SuppressWarnings({"StringEquality"})
141    @Override
142    public boolean equals(Object obj) {
143        if (obj == null) {
144            return false;
145        }
146        if (getClass() != obj.getClass()) {
147            return false;
148        }
149        final ViewNode other = (ViewNode) obj;
150        return !(this.name != other.name && (this.name == null || !this.name.equals(other.name)));
151    }
152
153    @Override
154    public String toString() {
155        return name;
156    }
157
158    @Override
159    public int hashCode() {
160        int hash = 5;
161        hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0);
162        return hash;
163    }
164
165    public static class Property {
166        public String name;
167        public String value;
168
169        @Override
170        public String toString() {
171            return name + '=' + value;
172        }
173
174        @SuppressWarnings({"StringEquality"})
175        @Override
176        public boolean equals(Object obj) {
177            if (obj == null) {
178                return false;
179            }
180            if (getClass() != obj.getClass()) {
181                return false;
182            }
183            final Property other = (Property) obj;
184            if (this.name != other.name && (this.name == null || !this.name.equals(other.name))) {
185                return false;
186            }
187            return !(this.value != other.value && (this.value == null || !this.value.equals(other.value)));
188        }
189
190        @Override
191        public int hashCode() {
192            int hash = 5;
193            hash = 61 * hash + (this.name != null ? this.name.hashCode() : 0);
194            hash = 61 * hash + (this.value != null ? this.value.hashCode() : 0);
195            return hash;
196        }
197    }
198
199    interface StateListener {
200        void nodeStateChanged(ViewNode node);
201        void nodeIndexChanged(ViewNode node);
202    }
203}
204