content: /*
   * Copyright (C) 2015-2023 Emanuel Moecklin
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package com.onegravity.rteditor.api;
  
  import android.content.Context;
  import android.util.Log;
  
  import com.onegravity.rteditor.api.media.RTAudio;
  import com.onegravity.rteditor.api.media.RTAudioImpl;
  import com.onegravity.rteditor.api.media.RTImage;
  import com.onegravity.rteditor.api.media.RTImageImpl;
  import com.onegravity.rteditor.api.media.RTMediaSource;
  import com.onegravity.rteditor.api.media.RTMediaType;
  import com.onegravity.rteditor.api.media.RTVideo;
  import com.onegravity.rteditor.api.media.RTVideoImpl;
  import com.onegravity.rteditor.media.MediaUtils;
  import com.onegravity.rteditor.utils.Helper;
  
  import com.onegravity.rteditor.utils.io.IOUtils;
  
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  
  /**
   * This is a basic implementation of the RTMediaFactory using either the
   * internal (as in Context.context.getFilesDir() or the primary external
   * file system (as in Context.getExternalFilesDir(String).
   */
  public class RTMediaFactoryImpl implements RTMediaFactory<RTImage, RTAudio, RTVideo> {
      private static final long serialVersionUID = 6970361368051595063L;
  
      private File mStoragePath;
  
      public RTMediaFactoryImpl(Context context) {
          this(context, true);    // use external storage as default
      }
  
      public RTMediaFactoryImpl(Context context, boolean externalStorage) {
          mStoragePath = externalStorage ?
                  context.getExternalFilesDir(null) :
                  context.getFilesDir();
      }
  
      /**
       * Returns the absolute file path for a certain RTMediaType.
       * <p>
       * The media type specific path as provided by RTMediaType is appended to
       * the storage path (e.g. <storage area>/images for image files).
       */
      protected String getAbsolutePath(RTMediaType mediaType) {
          File mediaPath = new File(mStoragePath.getAbsolutePath(), mediaType.mediaPath());
          if (!mediaPath.exists()) {
              mediaPath.mkdirs();
          }
          return mediaPath.getAbsolutePath();
      }
  
      /*
       * Use case 1: Inserting media objects into the rich text editor.
       *
       * This default implementation copies all files into the dedicated media
       * storage area.
       */
  
      @Override
      /* @inheritDoc */
      public RTImage createImage(RTMediaSource mediaSource) {
          File targetFile = loadMedia(mediaSource);
          return targetFile == null ? null :
                  new RTImageImpl(targetFile.getAbsolutePath());
      }
  
      @Override
      /* @inheritDoc */
      public RTAudio createAudio(RTMediaSource mediaSource) {
          File targetFile = loadMedia(mediaSource);
          return targetFile == null ? null :
                  new RTAudioImpl(targetFile.getAbsolutePath());
      }
  
      @Override
      /* @inheritDoc */
      public RTVideo createVideo(RTMediaSource mediaSource) {
          File targetFile = loadMedia(mediaSource);
          return targetFile == null ? null :
                  new RTVideoImpl(targetFile.getAbsolutePath());
      }
  
      private File loadMedia(RTMediaSource mediaSource) {
          File targetPath = new File(getAbsolutePath(mediaSource.getMediaType()));
          File targetFile = MediaUtils.createUniqueFile(targetPath,
                  mediaSource.getName(),
                  mediaSource.getMimeType(),
                  false);
  
          copyFile(mediaSource.getInputStream(), targetFile);
  
          return targetFile;
      }
  
      private void copyFile(InputStream in, File targetFile) {
          OutputStream out = null;
          try {
              out = new FileOutputStream(targetFile);
              IOUtils.copy(in, out);
          } catch (IOException ioe) {
              Log.e(getClass().getSimpleName(), ioe.getMessage(), ioe);
          } finally {
              Helper.closeQuietly(out);
              Helper.closeQuietly(in);
          }
      }
  
      /*
       * Use case 2: Load a rich text with referenced media objects into the rich
       * text editor.
       *
       * This default implementation doesn't apply any transformations to the path
       * because the files are stored in the file system where they can be
       * accessed directly by the rich text editor (via ImageSpan).
       */
  
      @Override
      /* @inheritDoc */
      public RTImage createImage(String path) {
          return new RTImageImpl(path);
      }
  
      @Override
      /* @inheritDoc */
      public RTAudio createAudio(String path) {
          return new RTAudioImpl(path);
      }
  
      @Override
      /* @inheritDoc */
      public RTVideo createVideo(String path) {
          return new RTVideoImpl(path);
      }
  
  }