package Site::Config; ###### Site-wide configuration information
###	$Id: Config.pm,v 1.13 2003/05/09 20:29:00 admin Exp $
#	This file is part of Combo and is licensed under the GPL and LGPL.
#	Copyright 2001-2002 by the authors.  See README and LICENSE files
#	for more details or see http://penguinsong.org/.

### Site::Config holds a Combo site's global configuration information.

#	In mod_perl it can be a persistant global, so it _must not_ be used
#	for request-specific information -- that's what CGI is for, though
#	splitQuery may be better in some cases.  If virtual hosting is used,
#	there will have to be a hash keyed on SERVER_NAME, which is why
#	SERVER_NAME is a parameter to getConfig.

#	Usage:  my $cfg = new Config;
#	   or:  my $cfg = new Config($ENV{SERVER_NAME});

#	In most cases, the Site::Config will be accessible through the Context
#	object, as $cxt->getConfig()

BEGIN {
    use Exporter();
    use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
    $cvsid = '$Id: Config.pm,v 1.13 2003/05/09 20:29:00 admin Exp $ ';
    $cvsid =~ /,v ([0-9]+.[0-9]+)/;
    $VERSION=$1;
    @ISA = qw(Exporter);
    @EXPORT = ( );
}

use Site::Util;
use AMP::Tagset;
use Type::Manager;

##########################################################################
###
### Constructors:
###

### Config->new()
#	Obtain a new (or cached) Combo configuration instance for the 
#	current server.  (Virtual hosting in mod_perl requires that we
#	hash on the server name to get a cached instance.)
#	
sub new {
    my ($class, $server_name) = (@_);
    $server_name = $ENV{'SERVER_NAME'} unless $server_name;
    my $self = { 'server.name' => $server_name,
	     };

    $self = bless $self, $class;
    $self-> initialize();
    return $self;
}

##########################################################################
###
### Access Functions:
###

### $c->get(name) -> value
#	get a site configuration property
sub get {
    my ($self, $n) = (@_);
    return $self->{$n};
}

sub getServerName {
    my $self = shift;
    return $self->{'server.name'};
}

### $c->getSiteDir
sub getSiteDir {
    my $self = shift;
    return $self->{'site.dir'};
}

### $c->getDocRoot
sub getDocRoot {
    my $self = shift;
    return $self->{'_doc_root'};
}

sub getSiteFile {
    my $self = shift;
    return $self->{'_site_file'};
}

### $c->getTypeManager
sub getTypeManager {
    my $self = shift;
    my $mgr = $self->{'_type_manager'};
    if (!defined $mgr) {
	$mgr = Type::Manager->new($self);
	$self->{'_type_manager'} = $mgr;
    }
    return $mgr;
}

### $c->getTemplateDir
#	Return the full path to the directory that contains tag templates
sub getTemplateDir {
    my $self = shift;
    my $tdir = $self->getDocRoot . $self->{'site.template.dir'};
    $tdir = "../site/templates" unless -d $tdir;
    return $tdir;
}

### $c->getHomePathPrefix
#	Return the URL prefix for a user home directory
sub getHomePathPrefix {
    my $self = shift;
    my $path = $self->{'site.home.path'};
    $path = "/m//" unless $path;
    return $path;
}

### $c->getBaseURL
#	Return a URL that points to the server base
sub getBaseURL {
    my $self = shift;
    $server_name = $ENV{'SERVER_NAME'};
    $port = $ENV{'SERVER_PORT'};
    $port = ($port == 80)? "" : ":$port";

    return "http://$server_name$port";
}

### $c->getAreaMap
sub getAreaMap {
    my $self = shift;

    my @urls = split(" ", $self->get("area.urls"));
    my @text = split(" ", $self->get("area.text"));

    my $hash = {};
    for (my $i = @text; --$i >= 0; ) { 
	$hash->{$urls[$i]} = $text[$i]; 
    }
    return $hash;
}


##########################################################################
### 
### Path Manipulation:
###

### $c->makeRealPath($path)
#	expand ...//... constructs in $path
#
sub makeRealPath {
    my ($self, $path) = @_;
    my $p = "$path";
    $p =~ s|//(.)(.)|/$1/$1$2/$1$2|;
    return $p;
}

### $c->makeVirtualPath($path)
#	replace /X/Xy constructs in $path with //
#
sub makeShortPath {
    my ($self, $path) = @_;
    my $p = "$path";
    $p =~ s|//(.)(.)|/$1/$1$2/$1$2|;
    return $p;
}

### $c->translatePath($path)
#	Translate a URL path into a file path
#
sub translatePath {
    my ($self, $path) = @_;
    return $self->getDocRoot . $path;
}


##########################################################################
### 
### Initialization:
###

### $c->findConfig()
#	Locate the configuration file. 
#	Set up the main configuration globals.
#
sub findConfig {
    my ($self) = @_;
    my $serverRoot = $ENV{SERVER_ROOT};

    # === these actually need to end up in instance variables ===
    # === and shouldn't be global if we're to have a virtual-hosted mod_perl

    my $docRoot = $ENV{DOCUMENT_ROOT};
    $self->{'_doc_root'} = $docRoot;
    $self->{'DOCROOT'} = $docRoot;

    # locate the site directory (COMBO_SITE_DIR, default /site)
    # Always relative to the document root.

    my $siteDir = $ENV{COMBO_SITE_DIR};
    $siteDir = '/site' unless $siteDir;
    $self->{'site.dir'} = $siteDir;

    # locate the site configuration file (COMBO_SITE_CF, default site.cf)
    # in $siteDir unless it contains a slash; if it doesn't _start with_
    # a slash it's relative to the cgi directory, which allows for defaults
    # that can't be edited or viewed from the web.

    # Should really look along a path.

    my $siteCF = $ENV{COMBO_SITE_CF};
    $siteCF = 'site.cf' unless $siteCF;
    $siteCF = "$docRoot$siteDir/$siteCF" unless $siteCF =~ m|/|;
    $siteCF = './site.cf' unless -f $siteCF;
    $siteCF = '../site/site.cf' unless -f $siteCF;

    $self->{'_site_file'} = $siteCF;
    return $siteCF;
}

### $c->initialize()
#	Initialize a CGI.
#
sub initialize {
    my ($self) = (@_);
    $siteCF = $self->findConfig();		# === for now do this every time

    readConfig($self, $self->getSiteFile);
    my $siteDir = $self->getSiteDir;
    # === not clear who used to set up $templateDir
    $templateDir = "$siteDir/templates" unless $templateDir;
    $self->{'site.template.dir'} = $templateDir;

    # set up areas

    # === in mod_perl, re-read $siteCF if it's changed.
}



###########################################################################
'Package loaded';
