import { InjectionToken } from "@angular/core";
import { Observable } from "rxjs";

export declare var WIDGET_VIEW_TOKEN: InjectionToken<string>;

/**
 * Interface for widget editor views.
 */
export declare interface WidgetEditor {
    /**
     * Initialze the view. Invoked when properties for the widget are resolved.
     * @param widgetMetadata The metadata of the widget.
     * @memberof {WidgetEditor}
     */
    initialize(widgetMetadata: WidgetMetadata): Observable<void>;

    /**
     * Sets property values.
     * @param propValues The values of the widget`s properties.
     * @memberof {WidgetEditor}
     */
    setValues(propValues: Dictionary): void;

    /**
     * Validates the property data and returns the validation result.
     *
     * @memberof {WidgetEditor}
     */
    validate(): Observable<ValidationResult>;

    /**
     * Invoke when action for saving or canceling is initiated and the input should be preprocessed.
     *
     * @param {ActionContext} context defines if the action should save the data or the new input will be discarded.
     *
     * @memberof {WidgetEditor}
     */
    actionExecuting(context: ActionContext): Observable<void>;

    /**
     * Retrieves the modified properties
     *
     * @memberof {WidgetEditor}
     */
    getModifiedProperties(): Array<PropertyData>;
}

/**
 * Interface for the widget properties information.
 */
export declare interface WidgetMetadata {
  /**
   * Collection of property names and values.
   *
   * @memberof {WidgetMetadata}
   */
    propertyValues: Dictionary;

  /**
   * Collection of properties and sections metadata.
   *
   * @memberof {WidgetMetadata}
   */
    propertyMetadata: Array<SectionData>;

    /**
   * Collection of properties metadata in a flat structure.
   *
   * @memberof {WidgetMetadata}
   */
    propertyMetadataFlat: Array<PropertyMetadata>;

    /**
   * The widget name.
   *
   * @memberof {WidgetMetadata}
   */
    name: string;

    /**
   * The widget caption.
   *
   * @memberof {WidgetMetadata}
   */
    caption: string;
}

/**
 * Interface for the property data.
 */
export declare interface PropertyData {
  /**
   * The property name.
   *
   * @memberof {PropertyData}
   */
    Name: string,

  /**
   * The property value.
   *
   * @memberof {PropertyData}
   */
    Value: string
}

/**
 * Interface for the section data.
 */
export declare interface SectionData {
  /**
   * The section name.
   *
   * @memberof {SectionData}
   */
    Name: string,

  /**
   * The section title.
   *
   * @memberof {SectionData}
   */
    Title: string

  /**
   * Collection of properties` metadata.
   *
   * @memberof {SectionData}
   */
    Properties: Array<PropertyMetadata>
}

/**
 *  Interface for the property metadata.
 */
export declare interface PropertyMetadata {
    /**
   * The property name.
   *
   * @memberof {PropertyMetadata}
   */
    Name: string;

    /**
   * The property title.
   *
   * @memberof {PropertyMetadata}
   */
    Title: string;

    /**
   * The property type.
   *
   * @memberof {PropertyMetadata}
   */
    Type: string;

    /**
   * The default value of the property.
   *
   * @memberof {PropertyMetadata}
   */
    DefaultValue: string;

    /**
   * The collection of meta properties.
   *
   * @memberof {PropertyMetadata}
   */
    Properties: { [key: string]: any }
}

/**
 *  Interface for action context.
 */
export declare interface ActionContext {
  /**
   * If the changes should be processed or discarded
   *
   * @memberof {ActionContext}
   */
    processChanges: boolean,
}

/**
 *  Interface for validation results.
 */
export declare interface ValidationResult {
    /**
   * If the changes are valid.
   *
   * @memberof {ValidationResult}
   */
    isValid: boolean

    /**
   * The validation message, when the validation fails.
   *
   * @memberof {ValidationResult}
   */
    message?: string
}

/**
 *  Interface for dictionary data structure.
 */
export declare interface Dictionary {
    /**
   * Key accessor for the dictionary items.
   *
   * @memberof {ComponentMetadata}
   */
    [key: string]: string
}
