content: package allen.town.podcast.parser.feed.namespace;
  
  import android.text.TextUtils;
  import android.util.Log;
  
  import allen.town.podcast.parser.feed.HandlerState;
  import allen.town.podcast.parser.feed.element.SyndElement;
  import org.xml.sax.Attributes;
  
  import java.util.concurrent.TimeUnit;
  
  import allen.town.podcast.model.feed.FeedMedia;
  import allen.town.podcast.parser.feed.element.AtomText;
  import allen.town.podcast.parser.feed.util.MimeTypeUtils;
  
  /** Processes tags from the http://search.yahoo.com/mrss/ namespace. */
  public class Media extends Namespace {
      private static final String TAG = "NSMedia";
  
      public static final String NSTAG = "media";
      public static final String NSURI = "http://search.yahoo.com/mrss/";
  
      private static final String CONTENT = "content";
      private static final String DOWNLOAD_URL = "url";
      private static final String SIZE = "fileSize";
      private static final String MIME_TYPE = "type";
      private static final String DURATION = "duration";
      private static final String DEFAULT = "isDefault";
      private static final String MEDIUM = "medium";
  
      private static final String MEDIUM_IMAGE = "image";
      private static final String MEDIUM_AUDIO = "audio";
      private static final String MEDIUM_VIDEO = "video";
  
      private static final String IMAGE = "thumbnail";
      private static final String IMAGE_URL = "url";
  
      private static final String DESCRIPTION = "description";
      private static final String DESCRIPTION_TYPE = "type";
  
      @Override
      public SyndElement handleElementStart(String localName, HandlerState state,
                                            Attributes attributes) {
          if (CONTENT.equals(localName)) {
              String url = attributes.getValue(DOWNLOAD_URL);
              String defaultStr = attributes.getValue(DEFAULT);
              String medium = attributes.getValue(MEDIUM);
              boolean validTypeMedia = false;
              boolean validTypeImage = false;
              boolean isDefault = "true".equals(defaultStr);
              String mimeType = MimeTypeUtils.getMimeType(attributes.getValue(MIME_TYPE), url);
  
              if (MEDIUM_AUDIO.equals(medium)) {
                  validTypeMedia = true;
                  mimeType = "audio/*";
              } else if (MEDIUM_VIDEO.equals(medium)) {
                  validTypeMedia = true;
                  mimeType = "video/*";
              } else if (MEDIUM_IMAGE.equals(medium) && (mimeType == null
                      || (!mimeType.startsWith("audio/") && !mimeType.startsWith("video/")))) {
                  // Apparently, some publishers explicitly specify the audio file as an image
                  validTypeImage = true;
                  mimeType = "image/*";
              } else {
                  if (MimeTypeUtils.isMediaFile(mimeType)) {
                      validTypeMedia = true;
                  } else if (MimeTypeUtils.isImageFile(mimeType)) {
                      validTypeImage = true;
                  }
              }
  
              if (state.getCurrentItem() != null && (state.getCurrentItem().getMedia() == null || isDefault)
                      && url != null && validTypeMedia) {
                  long size = 0;
                  String sizeStr = attributes.getValue(SIZE);
                  try {
                      size = Long.parseLong(sizeStr);
                  } catch (NumberFormatException e) {
                      Log.e(TAG, "Size \"" + sizeStr + "\" could not be parsed.");
                  }
  
                  int durationMs = 0;
                  String durationStr = attributes.getValue(DURATION);
                  if (!TextUtils.isEmpty(durationStr)) {
                      try {
                          long duration = Long.parseLong(durationStr);
                          durationMs = (int) TimeUnit.MILLISECONDS.convert(duration, TimeUnit.SECONDS);
                      } catch (NumberFormatException e) {
                          Log.e(TAG, "Duration \"" + durationStr + "\" could not be parsed");
                      }
                  }
                  FeedMedia media = new FeedMedia(state.getCurrentItem(), url, size, mimeType);
                  if (durationMs > 0) {
                      media.setDuration(durationMs);
                  }
                  state.getCurrentItem().setMedia(media);
              } else if (state.getCurrentItem() != null && url != null && validTypeImage) {
                  state.getCurrentItem().setImageUrl(url);
              }
          } else if (IMAGE.equals(localName)) {
              String url = attributes.getValue(IMAGE_URL);
              if (url != null) {
                  if (state.getCurrentItem() != null) {
                      state.getCurrentItem().setImageUrl(url);
                  } else {
                      if (state.getFeed().getImageUrl() == null) {
                          state.getFeed().setImageUrl(url);
                      }
                  }
              }
          } else if (DESCRIPTION.equals(localName)) {
              String type = attributes.getValue(DESCRIPTION_TYPE);
              return new AtomText(localName, this, type);
          }
          return new SyndElement(localName, this);
      }
  
      @Override
      public void handleElementEnd(String localName, HandlerState state) {
          if (DESCRIPTION.equals(localName)) {
              String content = state.getContentBuf().toString();
              if (state.getCurrentItem() != null) {
                  state.getCurrentItem().setDescriptionIfLonger(content);
              }
          }
      }
  }
  
  