package de.dtele.data {
  
  import com.adobe.net.MimeTypeMap;
  
  /**
   * Utility class for working with MIME types and file extensions
   * 
   * <p>Allows for guessing a MIME type from a file extension and vice versa.
   * Splitting a MIME type definition into its parts is also supported</p>
   * 
   * @author Mathias Brodala
   */
  public class MimeTypes extends MimeTypeMap {
    
    /**
     * The predefined map of MIME types
     */
    protected static const map:MimeTypeMap = new MimeTypeMap();
    
    /**
     * The generic MIME type used as fallback if detection fails
     */
    private static const genericMimeType:MimeType = new MimeType("application", "octet-stream");
    
    /**
     * Tries to retrieve the MIME most likely
     * used for a specific file extension
     * 
     * @param extension The file extension
     * @return The most likely MIME type
     */
    public static function getMimeType(extension:String):String {
      
      return map.getMimeType(extension);
    }
    
    /**
     * Tries to retrieve the file extension most
     * likely used for a specific MIME type
     * 
     * @param mimetype The MIME type
     * @return The most likely file extension
     * 
     */
    public static function getExtension(mimetype:String):String {
      
      return map.getExtension(mimetype);
    }
    
    /**
     * Splits a MIME type string into its components
     * and returns an object representing the result
     * 
     * Returns a generic type if processing failed
     * 
     * @param mimetype The MIME type
     * @return The MIME type representation
     */
    public static function split(mimetype:String):MimeType {
      
      try {
        
        var types:Array = mimetype.split("/", 2);
        var parameters:Object = null;
        // Try to get optional parameters like mediaType/subType;parameter1=value1;parameter2=value2
        var subTypeWithParameters:Array = types[1].split(";", 2);
        
        if (subTypeWithParameters.length > 1) {
          
          types[1] = subTypeWithParameters.unshift();
          parameters = {};
          
          for each (var parameter:String in subTypeWithParameters) {
            
            var parameterPair:Array = parameter.split("=");
            parameters[parameterPair[0]] = parameterPair[1];
          }
        }
        
        return new MimeType(types[0].toLowerCase(), types[1].toLowerCase(), parameters);
      } catch (e:TypeError) { /* Ignore, returning generic type below */ }
      
      return genericMimeType;
    }
    
    public static function addMimeType(mimetype:String, extensions:Array):void {
      
      map.addMimeType(mimetype, extensions);
    }
  }
}