addHtml(sprintf('
%s
', $this->getView()->escape($this->rule->rule_name)));
        $this->addHidden('rule_id', $this->rule_id);
        $this->addElement('select', 'source_id', array(
            'label'        => $this->translate('Source Name'),
            'multiOptions' => $this->enumImportSource(),
            'required'     => true,
            'class'        => 'autosubmit',
        ));
        if (! $this->hasObject() && ! $this->getSentValue('source_id')) {
            return;
        }
        $this->addElement('select', 'destination_field', array(
            'label'        => $this->translate('Destination Field'),
            'multiOptions' => $this->optionalEnum($this->listDestinationFields()),
            'required'     => true,
            'class'        => 'autosubmit',
        ));
        if ($this->getSentValue('destination_field')) {
            $destination = $this->getSentValue('destination_field');
        } elseif ($this->hasObject()) {
            $destination = $this->getObject()->destination_field;
        } else {
            return;
        }
        $isCustomvar = substr($destination, 0, 5) === 'vars.';
        if ($isCustomvar) {
            $varname = substr($destination, 5);
            $this->addElement('text', 'customvar', array(
                'label'    => $this->translate('Custom variable'),
                'required' => true,
                'ignore'   => true,
            ));
            if ($varname !== '*') {
                $this->setElementValue('destination_field', 'vars.*');
                $this->setElementValue('customvar', $varname);
                if ($this->hasObject()) {
                    $this->getObject()->destination_field = 'vars.*';
                }
            }
        }
        if ($destination === 'import') {
            $templates = $this->db->enumHostTemplates(); // ERR. type!
            $templates = array_combine($templates, $templates);
            $this->addElement('select', 'source_expression', array(
                'label'        => $this->translate('Template'), // Objecttype?
                'multiOptions' => $this->optionalEnum($templates),
                'required'     => true,
                'class'        => 'autosubmit',
            ));
        } else {
            $this->addSourceColumnElement();
        }
        if ($this->hasObject()) {
            if (($col = $this->getObject()->getSourceColumn()) === null) {
                $this->setElementValue('source_column', self::EXPRESSION);
            $this->addElement('text', 'source_expression', array(
                'label'    => $this->translate('Source Expression'),
                'required' => true,
            ));
            if ($this->getSentValue('source_column') === '${' . self::EXPRESSION . '}') {
                unset($this->source_column);
            }
            } else {
                $this->setElementValue('source_column', $col);
            }
        }
        if ($this->getSentValue('source_column') === self::EXPRESSION) {
            $this->addElement('text', 'source_expression', array(
                'label'    => $this->translate('Source Expression'),
                'required' => true,
            ));
            if ($this->getSentValue('source_column') === '${' . self::EXPRESSION . '}') {
                unset($this->source_column);
            }
        }
        /*
        if ($this->hasObject()) {
            // TODO: Add up/down links to table
            $this->addElement('text', 'priority', array(
                'label'       => $this->translate('Priority'),
                'description' => $this->translate('Priority for the specified source expression'),
                'required'    => true,
            ));
        }
        */
        /*
        TODO: Filter should be a modifier
        $this->addElement('select', 'use_filter', array(
            'label'        => $this->translate('Filter values'),
            'description'  => $this->translate('Whether you want to merge or replace the destination field. Makes no difference for strings'),
            'required'     => true,
            'multiOptions' => $this->optionalEnum(array(
                'y' => 'merge',
                'n' => 'replace'
            ))
        ));
        $this->addElement('text', 'filter_expression', array(
            'label'       => $this->translate('Filter Expression'),
            'description' => $this->translate('This allows to filter for specific parts within the given source expression'),
            'required'    => false,
            // TODO: validate filter
        )); 
        */
        if ($isCustomvar) {
            $this->addElement('select', 'merge_policy', array(
                'label'        => $this->translate('Merge Policy'),
                'description'  => $this->translate('Whether you want to merge or replace the destination field. Makes no difference for strings'),
                'required'     => true,
                'multiOptions' => $this->optionalEnum(array(
                    'merge'    => 'merge',
                    'override' => 'replace'
                ))
            ));
        } else {
            $this->addHidden('merge_policy', 'override');
        }
        $this->setButtons();
    }
    protected function addSourceColumnElement()
    {
        $error = false;
        try {
            $data = $this->listSourceColumns();
        } catch (Exception $e) {
            $data = array();
            $error = sprintf(
                $this->translate('Unable to fetch data: %s'),
                $e->getMessage()
            );
        }
        $this->addElement('select', 'source_column', array(
            'label'        => $this->translate('Source Column'),
            // TODO: List them as ${} ?
            'multiOptions' => $this->optionalEnum($data),
            'required'     => true,
            'class'        => 'autosubmit',
        ));
        if ($error) {
            $this->getElement('source_column')->addError($error);
        }
        return $this;
    }
    protected function enumImportSource()
    {
        $sources = $this->db->enumImportSource();
        $usedIds = $this->rule->listInvolvedSourceIds();
        if (empty($usedIds)) {
            return $this->optionalEnum($sources);
        }
        $usedSources = array();
        foreach ($usedIds as $id) {
            $usedSources[$id] = $sources[$id];
            unset($sources[$id]);
        }
        if (empty($sources)) {
            return $this->optionalEnum($usedSources);
        }
        return $this->optionalEnum(
            array(
                $this->translate('Used sources') => $usedSources,
                $this->translate('Other sources') => $sources
            )
        );
    }
    protected function listSourceColumns()
    {
        $columns = $this->getImportSource()->listColumns();
        $columns = array_combine($columns, $columns);
        $columns[self::EXPRESSION] = $this->translate('Custom expression');
        return $columns;
    }
    protected function listDestinationFields()
    {
        $fields = array();
        $dummy = $this->dummyObject();
        if ($dummy instanceof IcingaObject) {
            if ($dummy->supportsCustomvars()) {
                $fields['vars.*']  = $this->translate('Custom variable (vars.)');
            }
            if ($dummy->supportsImports()) {
                $fields['import']  = $this->translate('Inheritance (import)');
            }
        }
        foreach ($dummy->listProperties() as $prop) {
            if ($prop === 'id') continue;
            // TODO: allow those fields, but munge them (store ids)
            //if (preg_match('~_id$~', $prop)) continue;
            $fields[$prop] = $prop;
        }
        return $fields;
    }
    protected function getImportSource()
    {
        if ($this->importSource === null) {
            if ($this->hasObject()) {
                $src = ImportSource::load($this->object->source_id, $this->db);
            } else {
                $src = ImportSource::load($this->getSentValue('source_id'), $this->db);
            }
            $this->importSource = ImportSourceHook::loadByName($src->source_name, $this->db);
        }
        return $this->importSource;
    }
    public function onSuccess()
    {
        $sourceColumn = $this->getValue('source_column');
        if ($sourceColumn === self::EXPRESSION) {
            unset($this->source_column);
            $this->removeElement('source_column');
        } else {
            if (! $this->getElement('source_expression')) {
                $this->addHidden('source_expression', '${' . $sourceColumn . '}');
            }
        }
        $object = $this->getObject();
        $object->rule_id = $this->rule->id; // ?!
        $destination = $this->getValue('destination_field');
        if ($destination === 'vars.*') {
            $destination = $this->getValue('customvar');
            $object->destination_field = 'vars.' . $destination;
        }
        if ($object->hasBeenModified()) {
            if (! $object->hasBeenLoadedFromDb()) {
                $object->priority = $this->rule->getPriorityForNextProperty();
            }
        }
        return parent::onSuccess();
    }
    protected function dummyObject()
    {
        if ($this->dummyObject === null) {
            $this->dummyObject = IcingaObject::createByType(
                $this->rule->object_type,
                array(),
                $this->db
            );
        }
        return $this->dummyObject;
    }
    public function setRule(SyncRule $rule)
    {
        $this->rule = $rule;
        return $this;
    }
}