package LATMOS::Accounts::Web::Model::AttrForms;

use strict;
use warnings;
use base 'Catalyst::Model';

=head1 NAME

LATMOS::Accounts::Web::Model::AttrForms - Catalyst Model

=head1 DESCRIPTION

Catalyst Model.

=cut

my $attrs = {
    uid => [ 'Login', 'text:12' ],
    uidNumber => [ 'UID', 'text-U:6' ],
    gidNumber => [ 'GID', 'select:group:gidNumber' ],
    manager => [ 'Responsable', 'select-N:user' ],
    managedBy => [ 'Responsable', 'select-N:user' ],
    sn => [ 'Nom' ],
    givenName => [ 'Prénom' ],
    homeDirectory => [ 'Home', 'text-U:25' ],
    loginShell => [ 'Shell', 'text-A' ],
    physicalDeliveryOfficeName => [ 'Bureau' ],
    telephoneNumber => [ 'Téléphone' ],
    otherTelephone => [ 'Téléphone (autre)' ],
    company => [ 'Société', 'text-A' ],
    l => [ 'Ville' ],
    postalCode => [ 'Code postal' ],
    postOfficeBox => [ 'BP' ],
    department => [ 'Département', 'select-N:group' ],
    streetAddress => [ 'Rue', 'textarea' ],
    title => [ 'Fonction' ],
    expire => [ 'Expire le', 'date' ],
    st => [ 'État (US)' ],
    sutype => [ 'Structure admin.', 'select-N:sutype' ],
    exported => [ 'Propagé', 'label' ],
    locked => [ 'Vérouillé', 'checkbox' ],
    isMainAddress => [ 'Adresse principale', 'checkbox' ],
    site => [ 'Site', 'select-N:site' ],
    co => [ 'Pays' ],
    mail => [ 'Mail', 'text-U:30' ],
    contratType => [ 'Type de contrat', 'text-A' ],
    grade => [ 'Grade', 'text-A' ],
    facsimileTelephoneNumber => [ 'Fax', 'text' ],
    nickname => [ 'Nick', 'text-U:3' ],
    cn => [ 'Nom' ],
    initials => [ 'Initiales', 'text-U:5' ],
    create => [ 'Créer le' ],
    date => [ 'Modifié le' ],
};

my $forms = {
    user => {
        name => 'Système',
        acl => 'admin',
        attrs => [ qw(
            sn givenName description
            uid uidNumber gidNumber gecos homeDirectory loginShell
            mail initials nickname
            locked
            exported
            create
            date
        ) ],
    },
    useraddress => {
        name => 'Adresse',
        attrs => [ qw(
            initials
            mail
        ) ],
    },
    userstatus => {
        name => 'Status',
        attrs => [ qw(
            company
            manager
            department
            grade
            contratType
            expire
        ) ],
    },
    site => {
        name => 'Site',
        attrs => [ qw(
            description
            streetAddress
            postOfficeBox
            postalCode
            l
            st
            co
            facsimileTelephoneNumber
        ) ],
    },
    address => {
        name => 'Adresse',
        attrs => [ qw(
            isMainAddress
            telephoneNumber
            streetAddress
            postOfficeBox
            postalCode
            l
            st
            physicalDeliveryOfficeName
            site
            co
        ) ],
    },
    group => {
        name => 'Système',
        acl => 'admin',
        attrs => [ qw(
            gidNumber description
            managedBy
            sutype exported
        ) ],
    },
};

sub escape {
    my ($self, $text) = @_;
    $text ||= '';
    for ($text) {
        s/&/&amp;/g;
        s/</&lt;/g;
        s/>/&gt;/g;
        s/"/&quot;/g;
    }
    $text;
}

sub new {
    my ($class) = @_;
    bless({}, $class);
}

# call either OBJ or type + base

sub ACCEPT_CONTEXT {
    my ($self, $c, $form, $object, $base) = @_;
    my $new = {};
    $new->{c} = $c;
    $new->{form} = $form;
    $new->{object} = $object if (ref $object);
    $new->{base} = $base || ($object ? $object->base : undef) or return $self;
    $new->{otype} = ref $object ? $object->type : $object;
    bless($new, 'LATMOS::Accounts::Web::Model::AttrForms');
}

sub base {
    my ( $self ) = @_;
    $self->{base}
}

sub otype {
    my ($self) = @_;
    $self->{otype};
}

sub label {
    my ($self) = @_;
    $forms->{$self->{form}}->{name} || ''
}

sub attributes {
    my ($self, $for) = @_;
    grep { $_ }
    grep { $self->base->check_acl($self->{object} || $self->otype, $_, 'r') }
    grep { $self->base->get_field_name($self->otype, $_, $for || 'a') }
    @{ $forms->{$self->{form}}->{attrs} };
}

sub attr_label {
    my ($self, $attr) = @_;
    my $htmlname = ($self->{object} ? $self->{object}->id . '_' : '') . $attr;
    return sprintf('<label for="%s">%s</label>',
        $self->escape($htmlname),
        $self->escape($attrs->{$attr}[0] || $attr)
    );
}

sub attr_raw_value {
    my ($self, $attr) = @_;
    return $self->{c}->req->param($attr) ||
        ($self->{object} ? $self->{object}->get_c_field($attr) : '')
}

sub attr_field {
    my ($self, $attr, $type) = @_;
    my $modallow = $self->base->check_acl($self->{object}
        ? ($self->{object}, $attr, 'w')
        : ($self->otype, '@CREATE', 'w'));
    $type ||= $self->base->get_field_name($self->otype, $attr, 'w') && $modallow
        ? $attrs->{$attr}[1] || ''
        : 'label';
    # exception: gidNumber is used also in group, but we don't want
    # group list here, really the number !
    $type = $modallow ? 'text-U:6' : 'label' if (($self->{form} || '') =~ /^group/ && $attr eq 'gidNumber');
    $type ||= 'text';
    my $htmlname = $self->escape(($self->{object} ? $self->{object}->id . '_' :
            '') . $attr);
    for ($type) {
        /^textarea$/ and return sprintf(
            '<textarea id="%s" name="%s" cols="40">%s</textarea>',
            $self->escape($htmlname),
            $self->escape($htmlname),
            $self->escape($self->attr_raw_value($attr)),
        );
        /^label$/ and do {
            my $field = $self->escape(
                $self->attr_raw_value($attr)
            );
            $field =~ s/\n/<br>/g;
            return $field;
        };
        /^date$/ and do {
            my ($date, $time) = split(/ /, $self->attr_raw_value($attr) || '');
            if ($date && $date =~ /^(\d+)-(\d+)-(\d+)$/) {
                $date = "$3/$2/$1";
            }
            my $html = "\n" . q{<SCRIPT LANGUAGE="JavaScript" ID="js13">
            var cal13 = new CalendarPopup();
            </SCRIPT>} . "\n";
            $html .= sprintf(
                '<input type="text" id="%s" name="%s" value="%s" size="12">',
                $self->escape($htmlname),
                $self->escape($htmlname),
                $self->escape($date)
            );
            $html .= q{<DIV ID="testdiv1" STYLE="position:absolute;visibility:hidden;background-color:white;layer-background-color:white;"></DIV>};
            $html .= qq|
            <A HREF="#"
                onClick="cal13.select(document.forms[0].$htmlname,'${htmlname}_anc','dd/MM/yyyy');return false;"
                TITLE="cal13.select(document.forms[0].$htmlname,'${htmlname}_anc','dd/MM/yyyy');return false;"
                NAME="${htmlname}_anc" ID="${htmlname}_anc">
                <img src="| . $self->{c}->uri_for(qw(/static icons view-calendar-day.png))
                . qq{" style="ref"></A>
                } . "\n";
            return $html;
        };
        /^checkbox$/ and do {
            return sprintf('<input type="checkbox" name="%s"%s>',
                $self->escape($htmlname),
                $self->attr_raw_value($attr) ? '  checked="yes"' : ''
            ) . sprintf('<input type="hidden" name="%s">',
                $self->escape($htmlname));
        };
        /^select(-\w+)?:([^:]+)(?::(.*))?$/ and do {
            my $options = $1 || '';
            my $otype = $2;
            my $keyfield = $3;
            my $observe_keyfield = $keyfield || 'displayName';
            my $select = sprintf('<select id="%s" name="%s">',
                $self->escape($htmlname),
                $self->escape($htmlname)) . "\n";
            $select .= '<option value="">--</option>' . "\n" if ($options =~ /N/);
            my $value = $self->attr_raw_value($attr) || '';
            my $initial_observed = '';
            foreach my $id ($self->base->list_objects($otype)) {
                my $obj = $self->base->get_object($otype, $id) or next;
                my $val = $keyfield ? $obj->get_c_field($keyfield) : $id;
                $select .= sprintf(
                    '    <option value="%s"%s>%s</option>',
                    $self->escape($val || ''),
                    $value eq $val ? ' selected="selected"' : '',
                    $self->escape($id || ''),
                );
                $select .= "\n";
                $initial_observed = $obj->get_c_field($observe_keyfield) || ''
                    if($value eq $val);
            }
            $select .= "</select>\n";
            $select .= $self->{c}->prototype->observe_field( $htmlname, {
                update => "${htmlname}_span",
                url => $self->{c}->uri_for('/ajax', 'rawattr', $otype),
                frequency => 1,
                with   => "'attr=" . $observe_keyfield .
                "&id='+element.options[element.selectedIndex].text",
            }) .
            qq|<span id="${htmlname}_span">$initial_observed</span>|;
            return $select;
        };
        /^text(-\w+)?(?::(\d+))?/ and do {
            my $flag = $1 || '';
            my $textf = sprintf(
                '<input type="text" id="%s" name="%s" value="%s" size="%d">',
                $self->escape($htmlname),
                $self->escape($htmlname),
                $self->escape($self->attr_raw_value($attr)),
                $2 || 30,
            );
            if ($flag =~ /A/) {
            $textf .= qq|<span id="${htmlname}_auto_complete"></span>|;
            $textf .= "\n";
            $textf .= $self->{c}->prototype->auto_complete_field(
                $htmlname,
                {
                update => "${htmlname}_auto_complete",
                url => $self->{c}->uri_for('/ajax', 'attrvalues', $self->otype, $attr),
                indicator => "${htmlname}_stat", min_chars => 1,
                with => "'val='+document.getElementById('$htmlname').value",
                frequency => 2,
                }
            );
            }
            if ($flag =~ /U/) {
            $textf .= qq|<span id="${htmlname}_observer_uniq"></span>|;
            $textf .= "\n";
            $textf .= $self->{c}->prototype->observe_field(
                $htmlname,
                {
                update => "${htmlname}_observer_uniq",
                url => $self->{c}->uri_for('/ajax', 'objattrexist',
                    $self->otype, $attr),
                frequency => 2,
                indicator => "${htmlname}_stat", min_chars => 1,
                with => "'val='+document.getElementById('$htmlname').value" .
                    ($self->{object} ? "+'&exclude=" . $self->{object}->id . "'" :
                        ''),
                }
            );
            }
            $textf .= qq|<span style="display:none" id="${htmlname}_stat">Searching...</span>|;

            return $textf;
        };
    }
}

sub submit {
    my ($self) = @_;
    return sprintf(
        '<input type="submit" name="%s" value="Enregistrer">',
        $self->escape($self->label),
    );
}

sub set_attrs {
    my ($self) = @_;
    $self->{c}->req->param($self->label) or return;
    my $prefix = $self->{object}->id . '_';
    $self->{object}->set_c_fields(
        map {
            $_ =>
                ($attrs->{$_}[1] || '') eq 'checkbox'
                ? ($self->{c}->req->param("$prefix$_") ? 1 : 0)
                : ($self->{c}->req->param("$prefix$_") || undef)
        } grep { $self->base->get_field_name($self->otype, $_, 'w') } $self->attributes
    ) or return;
    $self->{object}->base->commit;
}

=head1 AUTHOR

Thauvin Olivier

=head1 LICENSE

This library is free software, you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

1;
