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 
18 package com.android.mms.model;
19 
20 import java.util.ArrayList;
21 
22 import android.util.Config;
23 import android.util.Log;
24 
25 import com.android.mms.layout.LayoutManager;
26 import com.android.mms.layout.LayoutParameters;
27 
28 public 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 
LayoutModel()47     public LayoutModel() {
48         mLayoutParams = LayoutManager.getInstance().getLayoutParameters();
49         // Create default root-layout and regions.
50         createDefaultRootLayout();
51         createDefaultImageRegion();
52         createDefaultTextRegion();
53     }
54 
LayoutModel(RegionModel rootLayout, ArrayList<RegionModel> regions)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 
createDefaultRootLayout()77     private void createDefaultRootLayout() {
78         mRootLayout = new RegionModel(null, 0, 0, mLayoutParams.getWidth(),
79                                                   mLayoutParams.getHeight());
80     }
81 
createDefaultImageRegion()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 
createDefaultTextRegion()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 
validateLayouts()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         // LayoutModel will re-construct when orientation changes, so we need to
114         // initialize mLayoutType here. Otherwise, the mLayoutType is alway default
115         // value (LAYOUT_BOTTOM_TEXT) after LayoutModel re-construct.
116         mLayoutType =
117                 (mImageRegion.getTop() == 0) ? LAYOUT_BOTTOM_TEXT : LAYOUT_TOP_TEXT;
118     }
119 
getRootLayout()120     public RegionModel getRootLayout() {
121         return mRootLayout;
122     }
123 
setRootLayout(RegionModel rootLayout)124     public void setRootLayout(RegionModel rootLayout) {
125         mRootLayout = rootLayout;
126     }
127 
getImageRegion()128     public RegionModel getImageRegion() {
129         return mImageRegion;
130     }
131 
setImageRegion(RegionModel imageRegion)132     public void setImageRegion(RegionModel imageRegion) {
133         mImageRegion = imageRegion;
134     }
135 
getTextRegion()136     public RegionModel getTextRegion() {
137         return mTextRegion;
138     }
139 
setTextRegion(RegionModel textRegion)140     public void setTextRegion(RegionModel textRegion) {
141         mTextRegion = textRegion;
142     }
143 
144     /**
145      * Get all regions except root-layout. The result is READ-ONLY.
146      */
getRegions()147     public ArrayList<RegionModel> getRegions() {
148         ArrayList<RegionModel> regions = new ArrayList<RegionModel>();
149         if (mImageRegion != null) {
150             regions.add(mImageRegion);
151         }
152         if (mTextRegion != null) {
153             regions.add(mTextRegion);
154         }
155         return regions;
156     }
157 
findRegionById(String rId)158     public RegionModel findRegionById(String rId) {
159         if (IMAGE_REGION_ID.equals(rId)) {
160             return mImageRegion;
161         } else if (TEXT_REGION_ID.equals(rId)) {
162             return mTextRegion;
163         } else {
164             for (RegionModel r : mNonStdRegions) {
165                 if (r.getRegionId().equals(rId)) {
166                     return r;
167                 }
168             }
169 
170             if (LOCAL_LOGV) {
171                 Log.v(TAG, "Region not found: " + rId);
172             }
173             return null;
174         }
175     }
176 
getLayoutWidth()177     public int getLayoutWidth() {
178         return mRootLayout.getWidth();
179     }
180 
getLayoutHeight()181     public int getLayoutHeight() {
182         return mRootLayout.getHeight();
183     }
184 
getBackgroundColor()185     public String getBackgroundColor() {
186         return mRootLayout.getBackgroundColor();
187     }
188 
changeTo(int layout)189     public void changeTo(int layout) {
190         if (mRootLayout == null) {
191             throw new IllegalStateException("Root-Layout uninitialized.");
192         }
193 
194         if (mLayoutParams == null) {
195             mLayoutParams = LayoutManager.getInstance().getLayoutParameters();
196         }
197 
198         if (mLayoutType != layout) {
199             switch (layout) {
200                 case LAYOUT_BOTTOM_TEXT: {
201                     mImageRegion.setTop(0);
202                     mTextRegion.setTop(mLayoutParams.getImageHeight());
203                     mLayoutType = layout;
204                     notifyModelChanged(true);
205                 }
206                 break;
207                 case LAYOUT_TOP_TEXT: {
208                     mImageRegion.setTop(mLayoutParams.getTextHeight());
209                     mTextRegion.setTop(0);
210                     mLayoutType = layout;
211                     notifyModelChanged(true);
212                 }
213                 break;
214                 default: {
215                     Log.w(TAG, "Unknown layout type: " + layout);
216                 }
217             }
218         } else {
219             if (LOCAL_LOGV) {
220                 Log.v(TAG, "Skip changing layout.");
221             }
222         }
223     }
224 
getLayoutType()225     public int getLayoutType() {
226         return mLayoutType;
227     }
228 
229     @Override
registerModelChangedObserverInDescendants( IModelChangedObserver observer)230     protected void registerModelChangedObserverInDescendants(
231             IModelChangedObserver observer) {
232         if (mRootLayout != null) {
233             mRootLayout.registerModelChangedObserver(observer);
234         }
235 
236         if (mImageRegion != null) {
237             mImageRegion.registerModelChangedObserver(observer);
238         }
239 
240         if (mTextRegion != null) {
241             mTextRegion.registerModelChangedObserver(observer);
242         }
243     }
244 
245     @Override
unregisterModelChangedObserverInDescendants( IModelChangedObserver observer)246     protected void unregisterModelChangedObserverInDescendants(
247             IModelChangedObserver observer) {
248         if (mRootLayout != null) {
249             mRootLayout.unregisterModelChangedObserver(observer);
250         }
251 
252         if (mImageRegion != null) {
253             mImageRegion.unregisterModelChangedObserver(observer);
254         }
255 
256         if (mTextRegion != null) {
257             mTextRegion.unregisterModelChangedObserver(observer);
258         }
259     }
260 
261     @Override
unregisterAllModelChangedObserversInDescendants()262     protected void unregisterAllModelChangedObserversInDescendants() {
263         if (mRootLayout != null) {
264             mRootLayout.unregisterAllModelChangedObservers();
265         }
266 
267         if (mImageRegion != null) {
268             mImageRegion.unregisterAllModelChangedObservers();
269         }
270 
271         if (mTextRegion != null) {
272             mTextRegion.unregisterAllModelChangedObservers();
273         }
274     }
275 }
276