package Apache::MIME;

use strict;
use vars qw($VERSION);
use LWP 5.36; #minimum version required
use LWP::MediaTypes qw(guess_media_type add_type add_encoding);   
use DynaLoader ();
use Apache ();
use Apache::ModuleConfig ();
use Apache::Constants qw(:common DIR_MAGIC_TYPE DECLINE_CMD);

$VERSION = '0.01';

if($ENV{MOD_PERL}) {
    no strict;
    @ISA = qw(DynaLoader);
    __PACKAGE__->bootstrap($VERSION);
}

sub DIR_MERGE {
    my($base, $add) = @_;
    my %new = ();

    for (qw(language_types handlers)) { 
	$base->{$_} ||= {}; 
	$add->{$_}  ||= {}; 
	%{ $new{$_} } = (%{ $base->{$_} }, %{ $add->{$_} });
    }
    for (qw(type handler)) {
	$new{$_} = $add->{$_} || $base->{$_};
    }

    return bless \%new, ref $base;
}

sub handler {
    my $r = shift;

    if(-d $r->finfo) {
	$r->content_type(DIR_MAGIC_TYPE);
	return OK;
    }

    my($type, @encoding) = guess_media_type $r->filename;
    my $cfg = Apache::ModuleConfig->get($r);

    $r->content_type($type) if $type;

    unshift @encoding, $r->content_encoding if $r->content_encoding;
    $r->content_encoding(join ", ", @encoding) if @encoding;

    for my $ext (LWP::MediaTypes::file_exts($r->filename)) {
	if(my $type = $cfg->{language_types}->{$ext}) {
	    my $ltypes = $r->content_languages;
	    push @$ltypes, $type;
	    $r->content_languages($ltypes);
	}

	if(my $type = $cfg->{handlers}->{$ext} and !$r->proxyreq) {
            $r->handler($type);
        }  
    }

    $r->content_type($cfg->{'type'}) if $cfg->{'type'};		
    $r->handler($cfg->{'handler'}) if $cfg->{'handler'};		
    
    return OK;
}

sub TypesConfig ($$$) {
    my($cfg, $parms, $file) = @_;
    $cfg->{types_config} = Apache->server_root_relative($file);

    LWP::MediaTypes::read_media_types($cfg->{types_config});

    #if we need to co-exist with mod_mime.c 
    return DECLINE_CMD if Apache->module("mod_mime.c");
}

sub AddType ($$@;@) {
    my($cfg, $parms, $type, $ext) = @_; 
    add_type($type, $ext);
}

sub AddEncoding ($$@;@) {
    my($cfg, $parms, $enc, $ext) = @_;
    add_encoding($enc, $ext);
}

sub SetHandler ($$$) {
    my($cfg, $parms, $handler) = @_;
    $cfg->{'handler'} = $handler;
}

sub AddHandler ($$@;@) {
    my($cfg, $parms, $handler, $ext) = @_; 
    $ext =~ s/^\.//;
    $cfg->{handlers}->{$ext} = $handler;
}

sub ForceType ($$$) {
    my($cfg, $parms, $type) = @_;
    $cfg->{type} = $type;
}

sub AddLanguage ($$@;@) {
    my($cfg, $parms, $language, $ext) = @_;
    $ext =~ s/^\.//;
    $cfg->{language_types}->{$ext} = lc $language;
}

1;
__END__
