package WIT::Opts;

# WIT - command line parsing subroutine
# Copyright (C) 2009 Matous J. Fialka, <http://mjf.cz/>
# Released under the terms of The MIT License

use strict;
use warnings;
use vars;

our (@ISA, @EXPORT);

BEGIN {
        require Exporter;

        @ISA    = qw(Exporter);
        @EXPORT = qw(getopts);
}

use WIT::Utils;

sub _handleopt ($%$%)
{
        my ($opt, $hsh, $arg, $ret) = @_;

        if (defined $hsh->{$opt} and ref($hsh->{$opt}) eq 'CODE') {
                $ret->{$opt} = &{$hsh->{$opt}}($arg);
        } else {
                if (defined $arg) {
                        $ret->{$opt} = $arg;
                } else {
                        $ret->{$opt}++;
                }
        }
        return;
}

sub getopts ($%;%)
{
        my ($rul, $hsh, $ret) = @_;
        my $was = 0;

        $hsh = {} unless defined $hsh;
        $ret = {} unless defined $ret;

        while ($_ = shift @ARGV) {
                last if /^--$/;
                unless (/^-(.)(.*)/) {
                        unshift @ARGV, $_;
                        last;
                }
                my ($opt, $arg) = ($1, $2);
                if ($rul =~ /\Q$opt\E(\:?)/) {
                        $was++;
                        if ($1 eq ':') {
                                $arg = shift @ARGV unless $arg;
                                fail "missing argument for the '-$opt' option"
                                    unless $arg;
                                _handleopt $opt, $hsh, $arg, $ret;
                        } else {
                                _handleopt $opt, $hsh, undef, $ret;
                                if ($arg) {
                                        $_ = "-$arg";
                                        redo;
                                }
                        }
                } else {
                        fail "option '-$opt' not known";
                }
        }
        return $was ? $ret : undef;
}

1;
