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.ui;
19
20import android.content.Context;
21import android.net.Uri;
22import android.util.Log;
23
24import com.android.mms.LogTag;
25import com.android.mms.model.AudioModel;
26import com.android.mms.model.ImageModel;
27import com.android.mms.model.RegionModel;
28import com.android.mms.model.SlideModel;
29import com.android.mms.model.SlideshowModel;
30import com.android.mms.model.TextModel;
31import com.android.mms.model.VideoModel;
32import com.google.android.mms.ContentType;
33import com.google.android.mms.MmsException;
34
35/**
36 * An utility to edit contents of a slide.
37 */
38public class SlideshowEditor {
39    private static final String TAG = LogTag.TAG;
40
41    public static final int MAX_SLIDE_NUM = 10;
42
43    private final Context mContext;
44    private SlideshowModel mModel;
45
46    public SlideshowEditor(Context context, SlideshowModel model) {
47        mContext = context;
48        mModel = model;
49    }
50
51    public void setSlideshow(SlideshowModel model) {
52        mModel = model;
53    }
54
55    /**
56     * Add a new slide to the end of message.
57     *
58     * @return true if success, false if reach the max slide number.
59     */
60    public boolean addNewSlide() {
61        int position = mModel.size();
62        return addNewSlide(position);
63    }
64
65    /**
66     * Add a new slide at the specified position in the message.
67     *
68     * @return true if success, false if reach the max slide number.
69     * @throws IndexOutOfBoundsException - if position is out of range
70     *         (position < 0 || position > size()).
71     */
72    public boolean addNewSlide(int position) {
73        int size = mModel.size();
74        if (size < MAX_SLIDE_NUM) {
75            SlideModel slide = new SlideModel(mModel);
76
77            TextModel text = new TextModel(
78                    mContext, ContentType.TEXT_PLAIN, generateTextSrc(mModel, size),
79                    mModel.getLayout().getTextRegion());
80            slide.add(text);
81
82            mModel.add(position, slide);
83            return true;
84        } else {
85            Log.w(TAG, "The limitation of the number of slides is reached.");
86            return false;
87        }
88    }
89
90    /**
91     * Generate an unique source for TextModel
92     *
93     * @param slideshow The current slideshow model
94     * @param position The expected position for the new model
95     * @return An unique source String
96     */
97    private String generateTextSrc(SlideshowModel slideshow, int position) {
98        final String prefix = "text_";
99        final String postfix = ".txt";
100
101        StringBuilder src = new StringBuilder(prefix).append(position).append(postfix);
102        boolean hasDupSrc = false;
103
104        do {
105            for (SlideModel model : slideshow) {
106                if (model.hasText()) {
107                    String testSrc = model.getText().getSrc();
108
109                    if (testSrc != null && testSrc.equals(src.toString())) {
110                        src = new StringBuilder(prefix).append(position + 1).append(postfix);
111                        hasDupSrc |= true;
112                        break;
113                    }
114                }
115                hasDupSrc = false;
116            }
117        } while (hasDupSrc);
118
119        return src.toString();
120    }
121
122    /**
123     * Add an existing slide at the specified position in the message.
124     *
125     * @return true if success, false if reach the max slide number.
126     * @throws IndexOutOfBoundsException - if position is out of range
127     *         (position < 0 || position > size()).
128     */
129    public boolean addSlide(int position, SlideModel slide) {
130        int size = mModel.size();
131        if (size < MAX_SLIDE_NUM) {
132            mModel.add(position, slide);
133            return true;
134        } else {
135            Log.w(TAG, "The limitation of the number of slides is reached.");
136            return false;
137        }
138    }
139
140    /**
141     * Remove one slide.
142     *
143     * @param position
144     */
145    public void removeSlide(int position) {
146        mModel.remove(position);
147    }
148
149    /**
150     * Remove all slides.
151     */
152    public void removeAllSlides() {
153        while (mModel.size() > 0) {
154            removeSlide(0);
155        }
156    }
157
158    /**
159     * Remove the text of the specified slide.
160     *
161     * @param position index of the slide
162     * @return true if success, false if no text in the slide.
163     */
164    public boolean removeText(int position) {
165        return mModel.get(position).removeText();
166    }
167
168    public boolean removeImage(int position) {
169        return mModel.get(position).removeImage();
170    }
171
172    public boolean removeVideo(int position) {
173        return mModel.get(position).removeVideo();
174    }
175
176    public boolean removeAudio(int position) {
177        return mModel.get(position).removeAudio();
178    }
179
180    public void changeText(int position, String newText) {
181        if (newText != null) {
182            SlideModel slide = mModel.get(position);
183            TextModel text = slide.getText();
184            if (text == null) {
185                text = new TextModel(mContext,
186                        ContentType.TEXT_PLAIN, generateTextSrc(mModel, position),
187                        mModel.getLayout().getTextRegion());
188                text.setText(newText);
189                slide.add(text);
190            } else if (!newText.equals(text.getText())) {
191                text.setText(newText);
192            }
193        }
194    }
195
196    public void changeImage(int position, Uri newImage) throws MmsException {
197        mModel.get(position).add(new ImageModel(
198                mContext, newImage, mModel.getLayout().getImageRegion()));
199    }
200
201    public void changeAudio(int position, Uri newAudio) throws MmsException {
202        AudioModel audio = new AudioModel(mContext, newAudio);
203        SlideModel slide = mModel.get(position);
204        slide.add(audio);
205        slide.updateDuration(audio.getDuration());
206    }
207
208    public void changeVideo(int position, Uri newVideo) throws MmsException {
209        VideoModel video = new VideoModel(mContext, newVideo,
210                mModel.getLayout().getImageRegion());
211        SlideModel slide = mModel.get(position);
212        slide.add(video);
213        slide.updateDuration(video.getDuration());
214    }
215
216    public void moveSlideUp(int position) {
217        mModel.add(position - 1, mModel.remove(position));
218    }
219
220    public void moveSlideDown(int position) {
221        mModel.add(position + 1, mModel.remove(position));
222    }
223
224    public void changeDuration(int position, int dur) {
225        if (dur >= 0) {
226            mModel.get(position).setDuration(dur);
227        }
228    }
229
230    public void changeLayout(int layout) {
231        mModel.getLayout().changeTo(layout);
232    }
233
234    public RegionModel getImageRegion() {
235        return mModel.getLayout().getImageRegion();
236    }
237
238    public RegionModel getTextRegion() {
239        return mModel.getLayout().getTextRegion();
240    }
241}
242