1/*
2 * Copyright (C) 2008 Esmertec AG.
3 * Copyright (C) 2008 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package com.android.mms.model;
19
20import java.util.ArrayList;
21
22import android.util.Config;
23import android.util.Log;
24
25import com.android.mms.layout.LayoutManager;
26import com.android.mms.layout.LayoutParameters;
27
28public class LayoutModel extends Model {
29    private static final String TAG = SlideModel.TAG;
30    private static final boolean DEBUG = false;
31    private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
32
33    public static final String IMAGE_REGION_ID = "Image";
34    public static final String TEXT_REGION_ID  = "Text";
35
36    public static final int LAYOUT_BOTTOM_TEXT = 0;
37    public static final int LAYOUT_TOP_TEXT    = 1;
38    public static final int DEFAULT_LAYOUT_TYPE = LAYOUT_BOTTOM_TEXT;
39
40    private int mLayoutType = DEFAULT_LAYOUT_TYPE;
41    private RegionModel mRootLayout;
42    private RegionModel mImageRegion;
43    private RegionModel mTextRegion;
44    private ArrayList<RegionModel> mNonStdRegions;
45    private LayoutParameters mLayoutParams;
46
47    public LayoutModel() {
48        mLayoutParams = LayoutManager.getInstance().getLayoutParameters();
49        // Create default root-layout and regions.
50        createDefaultRootLayout();
51        createDefaultImageRegion();
52        createDefaultTextRegion();
53    }
54
55    public LayoutModel(RegionModel rootLayout, ArrayList<RegionModel> regions) {
56        mLayoutParams = LayoutManager.getInstance().getLayoutParameters();
57        mRootLayout = rootLayout;
58        mNonStdRegions = new ArrayList<RegionModel>();
59
60        for (RegionModel r : regions) {
61            String rId = r.getRegionId();
62            if (rId.equals(IMAGE_REGION_ID)) {
63                mImageRegion = r;
64            } else if (rId.equals(TEXT_REGION_ID)) {
65                mTextRegion = r;
66            } else {
67                if (LOCAL_LOGV) {
68                    Log.v(TAG, "Found non-standard region: " + rId);
69                }
70                mNonStdRegions.add(r);
71            }
72        }
73
74        validateLayouts();
75    }
76
77    private void createDefaultRootLayout() {
78        mRootLayout = new RegionModel(null, 0, 0, mLayoutParams.getWidth(),
79                                                  mLayoutParams.getHeight());
80    }
81
82    private void createDefaultImageRegion() {
83        if (mRootLayout == null) {
84            throw new IllegalStateException("Root-Layout uninitialized.");
85        }
86
87        mImageRegion = new RegionModel(IMAGE_REGION_ID, 0, 0,
88                mRootLayout.getWidth(), mLayoutParams.getImageHeight());
89    }
90
91    private void createDefaultTextRegion() {
92        if (mRootLayout == null) {
93            throw new IllegalStateException("Root-Layout uninitialized.");
94        }
95
96        mTextRegion = new RegionModel(
97                TEXT_REGION_ID, 0, mLayoutParams.getImageHeight(),
98                mRootLayout.getWidth(), mLayoutParams.getTextHeight());
99    }
100
101    private void validateLayouts() {
102        if (mRootLayout == null) {
103            createDefaultRootLayout();
104        }
105
106        if (mImageRegion == null) {
107            createDefaultImageRegion();
108        }
109
110        if (mTextRegion == null) {
111            createDefaultTextRegion();
112        }
113    }
114
115    public RegionModel getRootLayout() {
116        return mRootLayout;
117    }
118
119    public void setRootLayout(RegionModel rootLayout) {
120        mRootLayout = rootLayout;
121    }
122
123    public RegionModel getImageRegion() {
124        return mImageRegion;
125    }
126
127    public void setImageRegion(RegionModel imageRegion) {
128        mImageRegion = imageRegion;
129    }
130
131    public RegionModel getTextRegion() {
132        return mTextRegion;
133    }
134
135    public void setTextRegion(RegionModel textRegion) {
136        mTextRegion = textRegion;
137    }
138
139    /**
140     * Get all regions except root-layout. The result is READ-ONLY.
141     */
142    public ArrayList<RegionModel> getRegions() {
143        ArrayList<RegionModel> regions = new ArrayList<RegionModel>();
144        if (mImageRegion != null) {
145            regions.add(mImageRegion);
146        }
147        if (mTextRegion != null) {
148            regions.add(mTextRegion);
149        }
150        return regions;
151    }
152
153    public RegionModel findRegionById(String rId) {
154        if (IMAGE_REGION_ID.equals(rId)) {
155            return mImageRegion;
156        } else if (TEXT_REGION_ID.equals(rId)) {
157            return mTextRegion;
158        } else {
159            for (RegionModel r : mNonStdRegions) {
160                if (r.getRegionId().equals(rId)) {
161                    return r;
162                }
163            }
164
165            if (LOCAL_LOGV) {
166                Log.v(TAG, "Region not found: " + rId);
167            }
168            return null;
169        }
170    }
171
172    public int getLayoutWidth() {
173        return mRootLayout.getWidth();
174    }
175
176    public int getLayoutHeight() {
177        return mRootLayout.getHeight();
178    }
179
180    public String getBackgroundColor() {
181        return mRootLayout.getBackgroundColor();
182    }
183
184    public void changeTo(int layout) {
185        if (mRootLayout == null) {
186            throw new IllegalStateException("Root-Layout uninitialized.");
187        }
188
189        if (mLayoutParams == null) {
190            mLayoutParams = LayoutManager.getInstance().getLayoutParameters();
191        }
192
193        if (mLayoutType != layout) {
194            switch (layout) {
195                case LAYOUT_BOTTOM_TEXT: {
196                    mImageRegion.setTop(0);
197                    mTextRegion.setTop(mLayoutParams.getImageHeight());
198                    mLayoutType = layout;
199                    notifyModelChanged(true);
200                }
201                break;
202                case LAYOUT_TOP_TEXT: {
203                    mImageRegion.setTop(mLayoutParams.getTextHeight());
204                    mTextRegion.setTop(0);
205                    mLayoutType = layout;
206                    notifyModelChanged(true);
207                }
208                break;
209                default: {
210                    Log.w(TAG, "Unknown layout type: " + layout);
211                }
212            }
213        } else {
214            if (LOCAL_LOGV) {
215                Log.v(TAG, "Skip changing layout.");
216            }
217        }
218    }
219
220    public int getLayoutType() {
221        return mLayoutType;
222    }
223
224    @Override
225    protected void registerModelChangedObserverInDescendants(
226            IModelChangedObserver observer) {
227        if (mRootLayout != null) {
228            mRootLayout.registerModelChangedObserver(observer);
229        }
230
231        if (mImageRegion != null) {
232            mImageRegion.registerModelChangedObserver(observer);
233        }
234
235        if (mTextRegion != null) {
236            mTextRegion.registerModelChangedObserver(observer);
237        }
238    }
239
240    @Override
241    protected void unregisterModelChangedObserverInDescendants(
242            IModelChangedObserver observer) {
243        if (mRootLayout != null) {
244            mRootLayout.unregisterModelChangedObserver(observer);
245        }
246
247        if (mImageRegion != null) {
248            mImageRegion.unregisterModelChangedObserver(observer);
249        }
250
251        if (mTextRegion != null) {
252            mTextRegion.unregisterModelChangedObserver(observer);
253        }
254    }
255
256    @Override
257    protected void unregisterAllModelChangedObserversInDescendants() {
258        if (mRootLayout != null) {
259            mRootLayout.unregisterAllModelChangedObservers();
260        }
261
262        if (mImageRegion != null) {
263            mImageRegion.unregisterAllModelChangedObservers();
264        }
265
266        if (mTextRegion != null) {
267            mTextRegion.unregisterAllModelChangedObservers();
268        }
269    }
270}
271