import { customAttribute } from '../decorator/exported';
import { IAttribute, IListener, IBindingContext } from '../interface/exported';
import { BindingEngine } from '../binding/exported';


/**
 * css replaces style in elements
 *
 */
@customAttribute('css')
export class CssAttribute implements IAttribute {
    public $element: any;
    public $attribute: Attr;
    public $bindingContext: IBindingContext;
    private subscribeInternal: IListener;
    private value: string;
    private lastStyles: string[] = [];


    /**
     * created
     *
     */
    public created() {

        this.value = this.$attribute.value;
        this.$element.removeAttribute(this.$attribute.name);

        this.subscribeInternal = {
            name: 'cssAttribute:',
            value: this.value,
            call: (newValue: any, oldValue: any) => {
                if (oldValue !== newValue) {
                    this.splitAndInsert(newValue);
                }
            }
        };
        BindingEngine.subscribeClassProperty(this.$bindingContext, this.value, this.subscribeInternal);
    }



    /**
     * splits new value into array/maps it and sets it to style
     *
     */
    public splitAndInsert(value: string) {
        try {
            value = value === undefined || value === null ? '' : value;

            const x = value
                .split(';')
                .map((statement: any) => {
                    return statement.split(':');
                }).filter((value: any) => {
                    // needs to contains attribute and value, check array have 2
                    if (value.length === 2) {
                        return true;
                    } else {
                        return false;
                    }
                })
                .map((result: any) => {
                    return {
                        attribute: result[0],
                        value: result[1].replace(/ /g, '')
                    };
                });


            const newStyles: string[] = [];
            x.forEach((val) => {
                newStyles.push(val.attribute.trim());
                (<any>this.$element).style[val.attribute.trim()] = val.value.trim();
            });

            // remove if style isnt there anymore
            this.lastStyles.forEach((val) => {
                if (newStyles.indexOf(val) === -1) {
                    (<any>this.$element).style[val] = null;
                }
            });

            // save new styles so we know what to remove
            this.lastStyles = newStyles;

        } catch (e) {
            console.error('could not parse css values');
        }
    }



    /**
     * detached, remove binding
     *
     */
    public detached() {
        BindingEngine.unSubscribeClassProperty(this.$bindingContext, this.subscribeInternal);
    }

}
