<commit_before>/**
 * Copyright 2015-present Tuan Le.
 *
 * Licensed under the MIT License.
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://opensource.org/licenses/mit-license.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *------------------------------------------------------------------------
 *
 * @module ObservableDescriptor
 * @description -  An obserevable descriptor that allows an object property to emit
 *                 change events.
 *
 * @author Tuan Le (tuan.t.lei@gmail.com)
 */
/* @flow */
'use strict'; // eslint-disable-line

/* load Hyperflow */
import { Hf } from '../../../hyperflow';

/* load RxJs dependency */
import Rx from 'rxjs/Rx';

/**
 * @description - A emitter descriptor prototypes.
 *
 * ObservableDescriptorPrototype
 */
const ObservableDescriptorPrototype = Object.create({}).prototype = {
    /* ----- Prototype Definitions --------- */
    /**
     * @description - Check if subscriber is in subscription list.
     *
     * @method hasSubscriber
     * @param {string} handerKey
     * @return {boolean}
     */
    hasSubscriber: function hasSubscriber (handerKey) {
        const observable = this;
        const eventId = `${observable._id}.${handerKey}`;

        return observable._description.subscriber.hasOwnProperty(eventId);
    },
    /**
     * @description - Check if condition is in condition list.
     *
     * @method hasCondition
     * @param {string} conditionKey
     * @return {boolean}
     */
    hasCondition: function hasCondition (conditionKey) {
        const observable = this;

        return observable._description.condition.hasOwnProperty(conditionKey);
    },
    /**
     * @description - Get obvervable data stream.
     *
     * @method getStream
     * @return {object}
     */
    getStream: function getStream () {
        const observable = this;

        if (!observable._description.assigned) {
            Hf.log(`error`, `ObservableDescriptor.getStream - Descriptor as no assignment.`);
        } else {
            return observable._stream;
        }
    },
    /**
     * @description - Add a new subscriber to subscriber list.
     *
     * @method addSubscriber
     * @param {function} handler - Subscriber callback function.
     * @param {string} handerKey
     * @return void
     */
    addSubscriber: function addSubscriber (handler, handerKey) {
        if (!Hf.isFunction(handler)) {
            Hf.log(`error`, `ObservableDescriptor.addSubscriber - Input subscription handler function is invalid.`);
        } else if (!Hf.isString(handerKey)) {
            Hf.log(`error`, `ObservableDescriptor.addSubscriber - Input subscription handler key is invalid.`);
        } else {
            const observable = this;
            const eventId = `${observable._id}.${handerKey}`;

            if (!observable.hasSubscriber(eventId)) {
                observable._description.subscriber[eventId] = handler;
            }
        }
    },
    /**
     * @description - Remove a subscriber from subscriber list.
     *
     * @method removeSubscriber
     * @param {string} handerKey
     * @return void
     */
    removeSubscriber: function removeSubscriber (handerKey) {
        if (!Hf.isString(handerKey)) {
            Hf.log(`error`, `ObservableDescriptor.removeSubscriber - Input subscriber handler key is invalid.`);
        } else {
            const observable = this;
            const eventId = `${observable._id}.${handerKey}`;

            if (observable.hasSubscriber(eventId)) {
                observable._description.subscriber[eventId] = undefined;
                delete observable._description.subscriber[eventId];
            }
        }
    },
    /**
     * @description - Add a new condition to condition list.
     *
     * @method addCondition
     * @param {function} trigger - Trigger callback function.
     * @param {string} conditionKey
     * @return void
     */
    addCondition: function addCondition (trigger, conditionKey) {
        if (!Hf.isFunction(trigger)) {
            Hf.log(`error`, `ObservableDescriptor.addCondition - Input condition trigger function is invalid.`);
        } else if (!Hf.isString(conditionKey)) {
            Hf.log(`error`, `ObservableDescriptor.addCondition - Input condition key is invalid.`);
        } else {
            const observable = this;
            const eventId = `${observable._id}.${conditionKey}`;

            if (!observable.hasCondition(eventId)) {
                observable._description.condition[eventId] = trigger;
            }
        }
    },
    /**
     * @description - Remove a condition from condition list.
     *
     * @method removeCondition
     * @param {string} conditionKey
     * @return void
     */
    removeCondition: function removeCondition (conditionKey) {
        if (!Hf.isString(conditionKey)) {
            Hf.log(`error`, `ObservableDescriptor.removeCondition - Input condition key is invalid.`);
        } else {
            const observable = this;
            const eventId = `${observable._id}.${conditionKey}`;

            if (observable.hasCondition(eventId)) {
                observable._description.condition[eventId] = undefined;
                delete observable._description.condition[eventId];
            }
        }
    },
    /**
     * @description - Assign an observable description.
     *
     * @method assign
     * @param {object} descPreset - A descriptor preset object.
     * @return {object}
     */
    assign: function assign (descPreset) {
        if (!Hf.isSchema({
            key: `string|number`
        }).of(descPreset)) {
            Hf.log(`error`, `ObservableDescriptor.assign - Input descriptor preset object is invalid.`);
        } else {
            const observable = this;
            const {
                key,
                condition,
                subscriber
            } = Hf.fallback({
                condition: {},
                subscriber: {}
            }).of(descPreset);

            if (observable._description.assigned) {
                observable.unassign();
            }

            if (!Hf.isEmpty(condition)) {
                Hf.forEach(condition, (trigger, conditionKey) => {
                    observable.addCondition(trigger, conditionKey);
                });
            }

            if (!Hf.isEmpty(subscriber)) {
                Hf.forEach(subscriber, (handler, handlerKey) => {
                    observable.addSubscriber(handler, handlerKey);
                });
            }

            observable._observer = Rx.Subscriber.create(
                /**
                 * @description - On subscription to next incoming payload...
                 *
                 * @method next
                 * @param {object} payload
                 * @return void
                 */
                function next (payload) {
                    if (Hf.isSchema({
                        eventId: `string`
                    }).of(payload)) {
                        const {
                            eventId,
                            value
                        } = payload;
                        if (observable._description.subscriber.hasOwnProperty(eventId)) {
                            const handler = observable._description.subscriber[eventId];
                            handler(value);
                        }
                    } else {
                        Hf.log(`error`, `ObservableDescriptor.next - Payload event Id is invalid.`);
                    }
                },
                /**
                 * @description - On subscription to error...
                 *
                 * @method error
                 * @param {string} error
                 * @return void
                 */
                function error (_error) {
                    Hf.log(`error`, `ObservableDescriptor.error - Subscription error. ${_error.message}`);
                },
                /**
                 * @description - On subscription to completion...
                 *
                 * @method complete
                 * @return void
                 */
                function complete () {
                    Hf.log(`info`, `Subscription completed.`);
                }
            );

            return {
                /**
                 * @description - The target object to get this observable property.
                 *
                 * @method assign.to
                 * @param {object|array} target - Target object.
                 * @return void
                 */
                to: function to (target) {
                    if (Hf.isObject(target) || Hf.isArray(target)) {
                        if (target.hasOwnProperty(key)) {
                            observable._description.assigned = true;
                            observable._description.key = key;
                            observable._description.proxy = target;
                            observable._description.orgDesc = Object.getOwnPropertyDescriptor(target, key);

                            observable._stream = Rx.Observable.create((streamEmitter) => {
                                /* create the condition property for the assigned object */
                                Object.defineProperty(observable._description.proxy, key, {
                                    get: function get () {
                                        if (observable._description.orgDesc.hasOwnProperty(`get`)) {
                                            return observable._description.orgDesc.get();
                                        }
                                        return observable._description.orgDesc.value;
                                    },
                                    set: function set (value) {
                                        if (observable._description.orgDesc.hasOwnProperty(`set`)) {
                                            observable._description.orgDesc.set(value);
                                        } else {
                                            observable._description.orgDesc.value = value;
                                        }

                                        try {
                                            if (observable._description.orgDesc.hasOwnProperty(`get`)) {
                                                streamEmitter.next(observable._description.orgDesc.get());
                                            } else {
                                                streamEmitter.next(value);
                                            }
                                        } catch (error) {
                                            streamEmitter.error(error);
                                        }
                                    },
                                    configurable: true,
                                    enumerable: true
                                });
                            }).map((value) => {
                                const defaultPayload = {
                                    eventId: `${observable._id}`,
                                    value
                                };
                                if (!Hf.isEmpty(observable._description.condition)) {
                                    return Object.keys(observable._description.condition).reduce((payload, eventId) => {
                                        let context = {};
                                        const trigger = observable._description.condition[eventId];

                                        context[key] = value;
                                        if (trigger.call(context)) {
                                            payload = {
                                                eventId,
                                                value
                                            };
                                        }

                                        return payload;
                                    }, defaultPayload);
                                }
                                return defaultPayload;
                            });

                            observable._subscription = observable._stream.subscribe(observable._observer);
                        } else {
                            Hf.log(`error`, `ObservableDescriptor.assign.to - Property key:${key} is not defined.`);
                        }
                    } else {
                        Hf.log(`error`, `ObservableDescriptor.assign.to - Input target is invalid.`);
                    }
                }
            };
        }
    },
    /**
     * @description - Unassign an observable description.
     *
     * @method unassign
     * @return void
     */
    unassign: function unassign () {
        const observable = this;

        if (observable._description.assigned) {
            const key = observable._description.key;

            observable._observer.onComplete();
            observable._subscription.dispose();

            /* delete current property */
            observable._description.proxy[key] = undefined;
            delete observable._description.proxy[key];

            /* restore original property with it descriptor */
            if (observable._description.orgDesc.hasOwnProperty(`get`) || observable._description.orgDesc.hasOwnProperty(`set`)) {
                Object.defineProperty(observable._description.proxy, key, {
                    get: observable._description.orgDesc.get,
                    set: observable._description.orgDesc.set,
                    configurable: observable._description.orgDesc.configurable,
                    enumerable: observable._description.orgDesc.enumerable
                });
            } else {
                observable._description.proxy[key] = observable._description.orgDesc.value;
            }

            observable._description.assigned = false;
            observable._description.orgDesc = undefined;
            observable._description.proxy = undefined;
            observable._description.key = undefined;
            observable._stream = undefined;
            observable._observer = undefined;
            observable._subscription = undefined;
            Hf.clear(observable._description.condition);
            Hf.clear(observable._description.subscriber);
        }
    }
};

/**
 * @description - An observable descriptor module.
 *
 * @module ObservableDescriptor
 * @param {string} id - Descriptor Id.
 * @return {object}
 */
export default function ObservableDescriptor (id) {
    if (!Hf.isString(id)) {
        Hf.log(`error`, `ObservableDescriptor - Input descriptor Id is invalid.`);
    } else {
        const descriptor = Object.create(ObservableDescriptorPrototype, {
            _id: {
                value: id,
                writable: false,
                configurable: false,
                enumerable: false
            },
            _stream: {
                value: undefined,
                writable: true,
                configurable: true,
                enumerable: false
            },
            _observer: {
                value: undefined,
                writable: true,
                configurable: true,
                enumerable: false
            },
            _subscription: {
                value: undefined,
                writable: true,
                configurable: true,
                enumerable: false
            },
            _description: {
                value: {
                    assigned: false,
                    key: undefined,
                    orgDesc: undefined,
                    // TODO: Used es6 Proxy.
                    proxy: undefined,
                    subscriber: {},
                    condition: {}
                },
                writable: true,
                configurable: true,
                enumerable: false
            }
        });

        if (!Hf.isObject(descriptor)) {
            Hf.log(`error`, `ObservableDescriptor - Unable to create a computable descriptor instance.`);
        } else {
            const revealFrozen = Hf.compose(Hf.reveal, Object.freeze);
            /* reveal only the public properties and functions */
            return revealFrozen(descriptor);
        }
    }
}
<commit_msg>Changed onCompleted call to complete and dispose call to unsubscribe<commit_after>/**
 * Copyright 2015-present Tuan Le.
 *
 * Licensed under the MIT License.
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://opensource.org/licenses/mit-license.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *------------------------------------------------------------------------
 *
 * @module ObservableDescriptor
 * @description -  An obserevable descriptor that allows an object property to emit
 *                 change events.
 *
 * @author Tuan Le (tuan.t.lei@gmail.com)
 */
/* @flow */
'use strict'; // eslint-disable-line

/* load Hyperflow */
import { Hf } from '../../../hyperflow';

/* load RxJs dependency */
import Rx from 'rxjs/Rx';

/**
 * @description - A emitter descriptor prototypes.
 *
 * ObservableDescriptorPrototype
 */
const ObservableDescriptorPrototype = Object.create({}).prototype = {
    /* ----- Prototype Definitions --------- */
    /**
     * @description - Check if subscriber is in subscription list.
     *
     * @method hasSubscriber
     * @param {string} handerKey
     * @return {boolean}
     */
    hasSubscriber: function hasSubscriber (handerKey) {
        const observable = this;
        const eventId = `${observable._id}.${handerKey}`;

        return observable._description.subscriber.hasOwnProperty(eventId);
    },
    /**
     * @description - Check if condition is in condition list.
     *
     * @method hasCondition
     * @param {string} conditionKey
     * @return {boolean}
     */
    hasCondition: function hasCondition (conditionKey) {
        const observable = this;

        return observable._description.condition.hasOwnProperty(conditionKey);
    },
    /**
     * @description - Get obvervable data stream.
     *
     * @method getStream
     * @return {object}
     */
    getStream: function getStream () {
        const observable = this;

        if (!observable._description.assigned) {
            Hf.log(`error`, `ObservableDescriptor.getStream - Descriptor as no assignment.`);
        } else {
            return observable._stream;
        }
    },
    /**
     * @description - Add a new subscriber to subscriber list.
     *
     * @method addSubscriber
     * @param {function} handler - Subscriber callback function.
     * @param {string} handerKey
     * @return void
     */
    addSubscriber: function addSubscriber (handler, handerKey) {
        if (!Hf.isFunction(handler)) {
            Hf.log(`error`, `ObservableDescriptor.addSubscriber - Input subscription handler function is invalid.`);
        } else if (!Hf.isString(handerKey)) {
            Hf.log(`error`, `ObservableDescriptor.addSubscriber - Input subscription handler key is invalid.`);
        } else {
            const observable = this;
            const eventId = `${observable._id}.${handerKey}`;

            if (!observable.hasSubscriber(eventId)) {
                observable._description.subscriber[eventId] = handler;
            }
        }
    },
    /**
     * @description - Remove a subscriber from subscriber list.
     *
     * @method removeSubscriber
     * @param {string} handerKey
     * @return void
     */
    removeSubscriber: function removeSubscriber (handerKey) {
        if (!Hf.isString(handerKey)) {
            Hf.log(`error`, `ObservableDescriptor.removeSubscriber - Input subscriber handler key is invalid.`);
        } else {
            const observable = this;
            const eventId = `${observable._id}.${handerKey}`;

            if (observable.hasSubscriber(eventId)) {
                observable._description.subscriber[eventId] = undefined;
                delete observable._description.subscriber[eventId];
            }
        }
    },
    /**
     * @description - Add a new condition to condition list.
     *
     * @method addCondition
     * @param {function} trigger - Trigger callback function.
     * @param {string} conditionKey
     * @return void
     */
    addCondition: function addCondition (trigger, conditionKey) {
        if (!Hf.isFunction(trigger)) {
            Hf.log(`error`, `ObservableDescriptor.addCondition - Input condition trigger function is invalid.`);
        } else if (!Hf.isString(conditionKey)) {
            Hf.log(`error`, `ObservableDescriptor.addCondition - Input condition key is invalid.`);
        } else {
            const observable = this;
            const eventId = `${observable._id}.${conditionKey}`;

            if (!observable.hasCondition(eventId)) {
                observable._description.condition[eventId] = trigger;
            }
        }
    },
    /**
     * @description - Remove a condition from condition list.
     *
     * @method removeCondition
     * @param {string} conditionKey
     * @return void
     */
    removeCondition: function removeCondition (conditionKey) {
        if (!Hf.isString(conditionKey)) {
            Hf.log(`error`, `ObservableDescriptor.removeCondition - Input condition key is invalid.`);
        } else {
            const observable = this;
            const eventId = `${observable._id}.${conditionKey}`;

            if (observable.hasCondition(eventId)) {
                observable._description.condition[eventId] = undefined;
                delete observable._description.condition[eventId];
            }
        }
    },
    /**
     * @description - Assign an observable description.
     *
     * @method assign
     * @param {object} descPreset - A descriptor preset object.
     * @return {object}
     */
    assign: function assign (descPreset) {
        if (!Hf.isSchema({
            key: `string|number`
        }).of(descPreset)) {
            Hf.log(`error`, `ObservableDescriptor.assign - Input descriptor preset object is invalid.`);
        } else {
            const observable = this;
            const {
                key,
                condition,
                subscriber
            } = Hf.fallback({
                condition: {},
                subscriber: {}
            }).of(descPreset);

            if (observable._description.assigned) {
                observable.unassign();
            }

            if (!Hf.isEmpty(condition)) {
                Hf.forEach(condition, (trigger, conditionKey) => {
                    observable.addCondition(trigger, conditionKey);
                });
            }

            if (!Hf.isEmpty(subscriber)) {
                Hf.forEach(subscriber, (handler, handlerKey) => {
                    observable.addSubscriber(handler, handlerKey);
                });
            }

            observable._observer = Rx.Subscriber.create(
                /**
                 * @description - On subscription to next incoming payload...
                 *
                 * @method next
                 * @param {object} payload
                 * @return void
                 */
                function next (payload) {
                    if (Hf.isSchema({
                        eventId: `string`
                    }).of(payload)) {
                        const {
                            eventId,
                            value
                        } = payload;
                        if (observable._description.subscriber.hasOwnProperty(eventId)) {
                            const handler = observable._description.subscriber[eventId];
                            handler(value);
                        }
                    } else {
                        Hf.log(`error`, `ObservableDescriptor.next - Payload event Id is invalid.`);
                    }
                },
                /**
                 * @description - On subscription to error...
                 *
                 * @method error
                 * @param {string} error
                 * @return void
                 */
                function error (_error) {
                    Hf.log(`error`, `ObservableDescriptor.error - Subscription error. ${_error.message}`);
                },
                /**
                 * @description - On subscription to completion...
                 *
                 * @method complete
                 * @return void
                 */
                function complete () {
                    Hf.log(`info`, `Subscription completed.`);
                }
            );

            return {
                /**
                 * @description - The target object to get this observable property.
                 *
                 * @method assign.to
                 * @param {object|array} target - Target object.
                 * @return void
                 */
                to: function to (target) {
                    if (Hf.isObject(target) || Hf.isArray(target)) {
                        if (target.hasOwnProperty(key)) {
                            observable._description.assigned = true;
                            observable._description.key = key;
                            observable._description.proxy = target;
                            observable._description.orgDesc = Object.getOwnPropertyDescriptor(target, key);

                            observable._stream = Rx.Observable.create((streamEmitter) => {
                                /* create the condition property for the assigned object */
                                Object.defineProperty(observable._description.proxy, key, {
                                    get: function get () {
                                        if (observable._description.orgDesc.hasOwnProperty(`get`)) {
                                            return observable._description.orgDesc.get();
                                        }
                                        return observable._description.orgDesc.value;
                                    },
                                    set: function set (value) {
                                        if (observable._description.orgDesc.hasOwnProperty(`set`)) {
                                            observable._description.orgDesc.set(value);
                                        } else {
                                            observable._description.orgDesc.value = value;
                                        }

                                        try {
                                            if (observable._description.orgDesc.hasOwnProperty(`get`)) {
                                                streamEmitter.next(observable._description.orgDesc.get());
                                            } else {
                                                streamEmitter.next(value);
                                            }
                                        } catch (error) {
                                            streamEmitter.error(error);
                                        }
                                    },
                                    configurable: true,
                                    enumerable: true
                                });
                            }).map((value) => {
                                const defaultPayload = {
                                    eventId: `${observable._id}`,
                                    value
                                };
                                if (!Hf.isEmpty(observable._description.condition)) {
                                    return Object.keys(observable._description.condition).reduce((payload, eventId) => {
                                        let context = {};
                                        const trigger = observable._description.condition[eventId];

                                        context[key] = value;
                                        if (trigger.call(context)) {
                                            payload = {
                                                eventId,
                                                value
                                            };
                                        }

                                        return payload;
                                    }, defaultPayload);
                                }
                                return defaultPayload;
                            });

                            observable._subscription = observable._stream.subscribe(observable._observer);
                        } else {
                            Hf.log(`error`, `ObservableDescriptor.assign.to - Property key:${key} is not defined.`);
                        }
                    } else {
                        Hf.log(`error`, `ObservableDescriptor.assign.to - Input target is invalid.`);
                    }
                }
            };
        }
    },
    /**
     * @description - Unassign an observable description.
     *
     * @method unassign
     * @return void
     */
    unassign: function unassign () {
        const observable = this;

        if (observable._description.assigned) {
            const key = observable._description.key;

            observable._observer.complete();
            observable._subscription.unsubscribe();

            /* delete current property */
            observable._description.proxy[key] = undefined;
            delete observable._description.proxy[key];

            /* restore original property with it descriptor */
            if (observable._description.orgDesc.hasOwnProperty(`get`) || observable._description.orgDesc.hasOwnProperty(`set`)) {
                Object.defineProperty(observable._description.proxy, key, {
                    get: observable._description.orgDesc.get,
                    set: observable._description.orgDesc.set,
                    configurable: observable._description.orgDesc.configurable,
                    enumerable: observable._description.orgDesc.enumerable
                });
            } else {
                observable._description.proxy[key] = observable._description.orgDesc.value;
            }

            observable._description.assigned = false;
            observable._description.orgDesc = undefined;
            observable._description.proxy = undefined;
            observable._description.key = undefined;
            observable._stream = undefined;
            observable._observer = undefined;
            observable._subscription = undefined;
            Hf.clear(observable._description.condition);
            Hf.clear(observable._description.subscriber);
        }
    }
};

/**
 * @description - An observable descriptor module.
 *
 * @module ObservableDescriptor
 * @param {string} id - Descriptor Id.
 * @return {object}
 */
export default function ObservableDescriptor (id) {
    if (!Hf.isString(id)) {
        Hf.log(`error`, `ObservableDescriptor - Input descriptor Id is invalid.`);
    } else {
        const descriptor = Object.create(ObservableDescriptorPrototype, {
            _id: {
                value: id,
                writable: false,
                configurable: false,
                enumerable: false
            },
            _stream: {
                value: undefined,
                writable: true,
                configurable: true,
                enumerable: false
            },
            _observer: {
                value: undefined,
                writable: true,
                configurable: true,
                enumerable: false
            },
            _subscription: {
                value: undefined,
                writable: true,
                configurable: true,
                enumerable: false
            },
            _description: {
                value: {
                    assigned: false,
                    key: undefined,
                    orgDesc: undefined,
                    // TODO: Used es6 Proxy.
                    proxy: undefined,
                    subscriber: {},
                    condition: {}
                },
                writable: true,
                configurable: true,
                enumerable: false
            }
        });

        if (!Hf.isObject(descriptor)) {
            Hf.log(`error`, `ObservableDescriptor - Unable to create a computable descriptor instance.`);
        } else {
            const revealFrozen = Hf.compose(Hf.reveal, Object.freeze);
            /* reveal only the public properties and functions */
            return revealFrozen(descriptor);
        }
    }
}
<|endoftext|>


<commit_before>/*******************************************************************************
 #      ____               __          __  _      _____ _       _               #
 #     / __ \              \ \        / / | |    / ____| |     | |              #
 #    | |  | |_ __   ___ _ __ \  /\  / /__| |__ | |  __| | ___ | |__   ___      #
 #    | |  | | '_ \ / _ \ '_ \ \/  \/ / _ \ '_ \| | |_ | |/ _ \| '_ \ / _ \     #
 #    | |__| | |_) |  __/ | | \  /\  /  __/ |_) | |__| | | (_) | |_) |  __/     #
 #     \____/| .__/ \___|_| |_|\/  \/ \___|_.__/ \_____|_|\___/|_.__/ \___|     #
 #           | |                                                                #
 #           |_|                 _____ _____  _  __                             #
 #                              / ____|  __ \| |/ /                             #
 #                             | (___ | |  | | ' /                              #
 #                              \___ \| |  | |  <                               #
 #                              ____) | |__| | . \                              #
 #                             |_____/|_____/|_|\_\                             #
 #                                                                              #
 #                              (c) 2010-2012 by                                #
 #           University of Applied Sciences Northwestern Switzerland            #
 #                     Institute of Geomatics Engineering                       #
 #                           martin.christen@fhnw.ch                            #
 ********************************************************************************
 *     Licensed under MIT License. Read the file LICENSE for more information   *
 *******************************************************************************/

goog.provide('owg.ogVector');

goog.require('owg.ObjectDefs');
goog.require('owg.ogObject');
goog.require('owg.Surface');

//------------------------------------------------------------------------------
/**
 * @constructor
 * @extends {ogObject}
 * @description Vector class (OpenWebGlobe object)
 * @author Martin Christen, martin.christen@fhnw.ch
 */
function ogVector()
{
   /** @type {string} */
   this.name = "ogGeometry";
   /** @type {number} */
   this.type = OG_OBJECT_GEOMETRY;
   /** @type {string} */
   this.jsonUrl = "";
   /** @type {?function(number)} */
   this.cbr = null;
   /** @type {?function(number)} */
   this.cbf = null;
   /** @type {Object} */
   this.options = null;
   /** @type {Array.<Surface>}*/
   this.surfaces = [];
   /**@type {number} */
   this.indexInRendererArray = -1;
   /** @type {number} */
   this.layerID = -1; //the id of the vector layer containing this geometry.
   /** @type {Array.<number>} */
   this.color = [1,1,1,1];
   /** @type {Array.<number>} */
   this.highlightcolor = [1,1,1,1];
   /** @type {string} */
   this.userid = "unknown";
   /** @type {number} */
   this.linewidth = 10; // in meters
   /** @type {number} */
   this.pointsize = 10; // in meters
   /** @type {number} */
   this.minelv = -1000;
   /** @type {number} */
   this.maxelv = 9000;
}
//------------------------------------------------------------------------------
/** @extends {ogObject} */
ogVector.prototype = new ogObject();

//------------------------------------------------------------------------------
/**
 * @description parse options
 * @param {Object} options
 * @ignore
 */
ogVector.prototype.ParseOptions = function(options)
{
   this.options = options;

   if(options["url"])
   {
      if (options["type"] == "GeoJSON")
      {
         this.LoadGeoJSON(options["url"]);
      }
   }

}
//------------------------------------------------------------------------------
/**
 * @description Called when object is destroyed. Never call manually.
 * @ignore
 */
ogVector.prototype._OnDestroy = function()
{
   var renderer = this._GetVectorRenderer();
   renderer.RemoveVector(this.indexInRendererArray);
}
//------------------------------------------------------------------------------
/**
 *  @returns {VectorRenderer} the geometry-renderer
 */
ogVector.prototype._GetVectorRenderer = function()
{
   /** @type {VectorRenderer} */
   var renderer = null;
   /** @type {ogScene} */
   var scene = /** @type ogScene */this.parent;
   /** @type {ogContext} */
   var context =  /** @type ogContext */scene.parent;
   // Get the engine
   /** @type {engine3d} */
   var engine = context.engine;

   // test if there is a scenegraph attached
   if (engine.scene)
   {
      if (engine.scene.nodeRenderObject)
      {
         renderer = engine.scene.nodeRenderObject.vectorrenderer;
      }
   }
   return renderer;
}
//------------------------------------------------------------------------------
/**
 * @description retrieve Engine
 * @return {engine3d}
 */
ogVector.prototype._GetEngine = function()
{
   /** @type {VectorRenderer} */
   var renderer = null;
   /** @type {ogScene} */
   var scene = /** @type ogScene */this.parent;
   /** @type {ogContext} */
   var context =  /** @type ogContext */scene.parent;
   // Get the engine
   /** @type {engine3d} */
   var engine = context.engine;

   return engine;
}
//------------------------------------------------------------------------------
/**
 * @description hides the geometry
 */
ogVector.prototype.Hide = function()
{

}
//------------------------------------------------------------------------------
/**
 * @description shows the geometry
 */
ogGeometry.prototype.Show = function()
{

   if(this.ogpointsprite != null)
   {
      this.ogpointsprite.Show();
   }
   else
   {
      for(var j=0;j<this.meshes_og.length;j++)
      {
         /**@type {ogMeshObject} */
         var mesh = /**@type {ogMeshObject} */this.meshes_og[j];
         mesh.Show();
      }
   }
}
//------------------------------------------------------------------------------
/**
 * @description download callback
 * @ignore
 */
ogVector.prototype._cbfjsondownload = function()
{
   if (this.http.readyState==4)
   {
      if(this.http.status==404)
      {
         if (this.cbf)
         {
            this.cbf(this.id);
         }
      }
      else
      {
         var data=this.http.responseText;
         var jsonobj = goog.json.parse(data);
         this.CreateFromJSONObject(jsonobj);
      }
   }
}

//------------------------------------------------------------------------------
/**
 * @description Load model data from json object
 * @param {Object} jsonobject the json object.
 */
ogVector.prototype.CreateFromJSONObject = function(jsonobject)
{
   ogLog("CreateFromJSONObject");
   var gc = new GeoCoord();
   var cart0 = [0,0,0];
   var cart1 = [0,0,0];
   var bCreated = false;

   if(jsonobject['type']=="FeatureCollection")
   {
      ogLog("[GeoJSON Parser] type = FeatureCollection");
      if (goog.isDef(jsonobject['features']))
      {
         var feature = jsonobject['features'];
         var numFeatures = feature.length;
         ogLog("[GeoJSON Parser] numFeatures:" + numFeatures);
         for (var i=0;i<numFeatures;i++)
         {
            if (goog.isDef(feature[i]['type']) && feature[i]['type'] == "Feature")
            {
               if (goog.isDef(feature[i]['properties']) && goog.isDef(feature[i]['geometry']))
               {
                  var properties = feature[i]['properties'];
                  var geometry = feature[i]['geometry'];

                  // 1) read optional properties
                  if (goog.isDef(properties['id']))
                  {
                     ogLog("[GeoJSON Parser] Found user property id=" + properties['id']);
                     this.userid = properties['id']; // todo: type check
                  }

                  if (goog.isDef(properties['color']))
                  {
                     ogLog("[GeoJSON Parser] Found user property color");
                     this.color = properties['color']; // todo: type check
                  }

                  if (goog.isDef(properties['highlightcolor']))
                  {
                     ogLog("[GeoJSON Parser] Found user property highlightcolor");
                     this.highlightcolor = properties['highlightcolor']; // todo: type check
                  }

                  if (goog.isDef(properties['linewidth'])) // LineString/MultiLineString only..
                  {
                     ogLog("[GeoJSON Parser] Found user property linewidth");
                     this.linewidth = properties['linewidth']; // todo: type check
                  }

                  if (goog.isDef(properties['pointsize'])) // Point, Multipoint only...
                  {
                     ogLog("[GeoJSON Parser] Found user property pointsize");
                     this.pointsize = properties['pointsize']; // todo: type check
                  }

                  // 2) Parse Geometry

                  if (goog.isDef(geometry['type']))
                  {
                     var geometrytype = geometry['type'];
                     if (geometrytype == "LineString")
                     {
                        var geopairs = [];
                        var geopairsrev = [];
                        if (goog.isDef(geometry['coordinates'] && goog.isArray(geometry['coordinates'])))
                        {
                           var coords = geometry['coordinates'];
                           var numcoords = coords.length;
                           if (numcoords > 1)
                           {
                              for (var j=0;j<numcoords;j++)
                              {
                                 var lng = coords[j][0];
                                 var lat = coords[j][1];

                                 gc.Set(lng, lat, this.maxelv);
                                 gc.ToCartesian(cart0);
                                 gc.Set(lng, lat, this.minelv);
                                 gc.ToCartesian(cart1);

                                 geopairs.push([cart0[0], cart0[1], cart0[2]]);
                                 geopairs.push([cart1[0], cart1[1], cart1[2]]);
                              }

                           }
                        }

                        var indexlist = [];
                        var pointlist = [];
                        if (geopairs.length >=2)
                        {
                           var idx = 0;

                           // todo: extrude
                           for (var j=0;j<geopairs.length;j++)
                           {
                              var pt = geopairs[j]; indexlist.push(idx); idx++;
                              pointlist.push(pt[0]); pointlist.push(pt[1]); pointlist.push(pt[2]);
                           }

                           /** @type {ObjectJSON} */
                           var object = {"VertexSemantic" : "", "Vertices" : null, "IndexSemantic":"", "Indices":null};
                           object["VertexSemantic"]  = "p";
                           object["IndexSemantic"] = "TRIANGLESTRIP";
                           object["Vertices"] = pointlist;
                           object["Indices"] = indexlist;

                           var engine = this._GetEngine();
                           var surface = new Surface(engine);

                           surface.CreateFromJSONObject(object, null, null, surface);
                           //surface.SolidCube([0,0.06,0],[2,0.002,2],[1,1,1,1]);

                           this.surfaces.push(surface);

                           bCreated = true;
                        }
                     }
                     else if (geometrytype == "MultiLineString")
                     {
                        ogError("MultiLineString is not yet supported")
                     }
                     else if (geometrytype == "Polygon")
                     {
                        ogError("Polygon is not yet supported")
                     }
                     else if (geometrytype == "MultiPolygon")
                     {
                        ogError("MultiPolygon is not yet supported")
                     }
                     else if (geometrytype == "Point")
                     {
                        ogError("Point is not yet supported")
                     }
                     else if (geometrytype == "MultiPoint")
                     {
                        ogError("MultiPoint is not yet supported")
                     }
                  }
               }
            }
         }
      }
   }
   else
   {
      // not yet supported...
   }

   if (bCreated)
   {
      var renderer = this._GetVectorRenderer();
      this.indexInRendererArray = renderer.AddVector(this.surfaces);
   }
}

//------------------------------------------------------------------------------
/**
 * @description Load surface-data from a JSON file.
 * @param {string} url the url to the JSON file.
 */
ogVector.prototype.LoadGeoJSON = function(url)
{
   if(url == null)
   {
      alert("invalid json-url");
      return;
   }
   this.jsonUrl=url;

   this.http=new window.XMLHttpRequest();
   this.http.open("GET",this.jsonUrl,true);
   //this.http.setRequestHeader("Cache-Control", "public");

   var me=this;
   this.http.onreadystatechange = function(){me._cbfjsondownload();};
   //this.http.onprogress = function(){me._cbfonprogress();}
   this.http.send();
}
//------------------------------------------------------------------------------

<commit_msg>further advances in vector rendering<commit_after>/*******************************************************************************
 #      ____               __          __  _      _____ _       _               #
 #     / __ \              \ \        / / | |    / ____| |     | |              #
 #    | |  | |_ __   ___ _ __ \  /\  / /__| |__ | |  __| | ___ | |__   ___      #
 #    | |  | | '_ \ / _ \ '_ \ \/  \/ / _ \ '_ \| | |_ | |/ _ \| '_ \ / _ \     #
 #    | |__| | |_) |  __/ | | \  /\  /  __/ |_) | |__| | | (_) | |_) |  __/     #
 #     \____/| .__/ \___|_| |_|\/  \/ \___|_.__/ \_____|_|\___/|_.__/ \___|     #
 #           | |                                                                #
 #           |_|                 _____ _____  _  __                             #
 #                              / ____|  __ \| |/ /                             #
 #                             | (___ | |  | | ' /                              #
 #                              \___ \| |  | |  <                               #
 #                              ____) | |__| | . \                              #
 #                             |_____/|_____/|_|\_\                             #
 #                                                                              #
 #                              (c) 2010-2012 by                                #
 #           University of Applied Sciences Northwestern Switzerland            #
 #                     Institute of Geomatics Engineering                       #
 #                           martin.christen@fhnw.ch                            #
 ********************************************************************************
 *     Licensed under MIT License. Read the file LICENSE for more information   *
 *******************************************************************************/

goog.provide('owg.ogVector');

goog.require('owg.ObjectDefs');
goog.require('owg.ogObject');
goog.require('owg.Surface');
goog.require('owg.poly2tri');

//------------------------------------------------------------------------------
/**
 * @constructor
 * @extends {ogObject}
 * @description Vector class (OpenWebGlobe object)
 * @author Martin Christen, martin.christen@fhnw.ch
 */
function ogVector()
{
   /** @type {string} */
   this.name = "ogGeometry";
   /** @type {number} */
   this.type = OG_OBJECT_GEOMETRY;
   /** @type {string} */
   this.jsonUrl = "";
   /** @type {?function(number)} */
   this.cbr = null;
   /** @type {?function(number)} */
   this.cbf = null;
   /** @type {Object} */
   this.options = null;
   /** @type {Array.<Surface>}*/
   this.surfaces = [];
   /**@type {number} */
   this.indexInRendererArray = -1;
   /** @type {number} */
   this.layerID = -1; //the id of the vector layer containing this geometry.
   /** @type {Array.<number>} */
   this.color = [1,1,1,1];
   /** @type {Array.<number>} */
   this.highlightcolor = [1,1,1,1];
   /** @type {string} */
   this.userid = "unknown";
   /** @type {number} */
   this.linewidth = 10; // in meters
   /** @type {number} */
   this.pointsize = 10; // in meters
   /** @type {number} */
   this.minelv = -1000;
   /** @type {number} */
   this.maxelv = 9000;
}
//------------------------------------------------------------------------------
/** @extends {ogObject} */
ogVector.prototype = new ogObject();

//------------------------------------------------------------------------------
/**
 * @description parse options
 * @param {Object} options
 * @ignore
 */
ogVector.prototype.ParseOptions = function(options)
{
   this.options = options;

   if(options["url"])
   {
      if (options["type"] == "GeoJSON")
      {
         this.LoadGeoJSON(options["url"]);
      }
   }

}
//------------------------------------------------------------------------------
/**
 * @description Called when object is destroyed. Never call manually.
 * @ignore
 */
ogVector.prototype._OnDestroy = function()
{
   var renderer = this._GetVectorRenderer();
   renderer.RemoveVector(this.indexInRendererArray);
}
//------------------------------------------------------------------------------
/**
 *  @returns {VectorRenderer} the geometry-renderer
 */
ogVector.prototype._GetVectorRenderer = function()
{
   /** @type {VectorRenderer} */
   var renderer = null;
   /** @type {ogScene} */
   var scene = /** @type ogScene */this.parent;
   /** @type {ogContext} */
   var context =  /** @type ogContext */scene.parent;
   // Get the engine
   /** @type {engine3d} */
   var engine = context.engine;

   // test if there is a scenegraph attached
   if (engine.scene)
   {
      if (engine.scene.nodeRenderObject)
      {
         renderer = engine.scene.nodeRenderObject.vectorrenderer;
      }
   }
   return renderer;
}
//------------------------------------------------------------------------------
/**
 * @description retrieve Engine
 * @return {engine3d}
 */
ogVector.prototype._GetEngine = function()
{
   /** @type {VectorRenderer} */
   var renderer = null;
   /** @type {ogScene} */
   var scene = /** @type ogScene */this.parent;
   /** @type {ogContext} */
   var context =  /** @type ogContext */scene.parent;
   // Get the engine
   /** @type {engine3d} */
   var engine = context.engine;

   return engine;
}
//------------------------------------------------------------------------------
/**
 * @description hides the geometry
 */
ogVector.prototype.Hide = function()
{

}
//------------------------------------------------------------------------------
/**
 * @description shows the geometry
 */
ogGeometry.prototype.Show = function()
{

   if(this.ogpointsprite != null)
   {
      this.ogpointsprite.Show();
   }
   else
   {
      for(var j=0;j<this.meshes_og.length;j++)
      {
         /**@type {ogMeshObject} */
         var mesh = /**@type {ogMeshObject} */this.meshes_og[j];
         mesh.Show();
      }
   }
}
//------------------------------------------------------------------------------
/**
 * @description download callback
 * @ignore
 */
ogVector.prototype._cbfjsondownload = function()
{
   if (this.http.readyState==4)
   {
      if(this.http.status==404)
      {
         if (this.cbf)
         {
            this.cbf(this.id);
         }
      }
      else
      {
         var data=this.http.responseText;
         var jsonobj = goog.json.parse(data);
         this.CreateFromJSONObject(jsonobj);
      }
   }
}

//------------------------------------------------------------------------------
/**
 * @description Load model data from json object
 * @param {Object} jsonobject the json object.
 */
ogVector.prototype.CreateFromJSONObject = function(jsonobject)
{
   ogLog("CreateFromJSONObject");
   var gc = new GeoCoord();
   var cart0 = [0,0,0];
   var cart1 = [0,0,0];
   var bCreated = false;

   if(jsonobject['type']=="FeatureCollection")
   {
      ogLog("[GeoJSON Parser] type = FeatureCollection");
      if (goog.isDef(jsonobject['features']))
      {
         var feature = jsonobject['features'];
         var numFeatures = feature.length;
         ogLog("[GeoJSON Parser] numFeatures:" + numFeatures);
         for (var i=0;i<numFeatures;i++)
         {
            if (goog.isDef(feature[i]['type']) && feature[i]['type'] == "Feature")
            {
               if (goog.isDef(feature[i]['properties']) && goog.isDef(feature[i]['geometry']))
               {
                  var properties = feature[i]['properties'];
                  var geometry = feature[i]['geometry'];

                  // 1) read optional properties
                  if (goog.isDef(properties['id']))
                  {
                     ogLog("[GeoJSON Parser] Found user property id=" + properties['id']);
                     this.userid = properties['id']; // todo: type check
                  }

                  if (goog.isDef(properties['color']))
                  {
                     ogLog("[GeoJSON Parser] Found user property color");
                     this.color = properties['color']; // todo: type check
                  }

                  if (goog.isDef(properties['highlightcolor']))
                  {
                     this.highlightcolor = properties['highlightcolor']; // todo: type check
                  }

                  if (goog.isDef(properties['linewidth'])) // LineString/MultiLineString only..
                  {
                     this.linewidth = properties['linewidth']; // todo: type check
                  }

                  if (goog.isDef(properties['pointsize'])) // Point, Multipoint only...
                  {
                     this.pointsize = properties['pointsize']; // todo: type check
                  }

                  if (goog.isDef(properties['minelv'])) // Point, Multipoint only...
                  {
                     this.minelv = properties['minelv']; // todo: type check
                  }

                  if (goog.isDef(properties['maxelv'])) // Point, Multipoint only...
                  {
                     this.maxelv = properties['maxelv']; // todo: type check
                  }

                  // 2) Parse Geometry

                  if (goog.isDef(geometry['type']))
                  {
                     var geometrytype = geometry['type'];
                     if (geometrytype == "LineString")
                     {
                        var geopairs = [];
                        if (goog.isDef(geometry['coordinates'] && goog.isArray(geometry['coordinates'])))
                        {
                           var coords = geometry['coordinates'];
                           var numcoords = coords.length;
                           if (numcoords > 1)
                           {
                              for (var j=0;j<numcoords;j++)
                              {
                                 var lng = coords[j][0];
                                 var lat = coords[j][1];

                                 gc.Set(lng, lat, this.maxelv);
                                 gc.ToCartesian(cart0);
                                 gc.Set(lng, lat, this.minelv);
                                 gc.ToCartesian(cart1);

                                 geopairs.push([cart0[0], cart0[1], cart0[2]]);
                                 geopairs.push([cart1[0], cart1[1], cart1[2]]);
                              }

                           }
                        }

                        var indexlist = [];
                        var pointlist = [];

                        var w = 0.5 * this.linewidth * CARTESIAN_SCALE_INV;

                        if (geopairs.length >=4)
                        {

                           var P0 = geopairs[0];
                           var P1 = geopairs[1];
                           var idx = 0;
                           var idx00, idx10, idx20, idx30;
                           var idx01, idx11, idx21, idx31;

                           for (var j=2;j<geopairs.length-1;j+=2)
                           {
                              var P2 = geopairs[j];
                              var P3 = geopairs[j+1];

                              // at this time P0,P1,P2,P3 is
                              // the quad to be extruded

                              /*indexlist.push(idx0);
                              indexlist.push(idx1);
                              indexlist.push(idx2);

                              indexlist.push(idx1);
                              indexlist.push(idx3);
                              indexlist.push(idx2);*/

                              var ux = P2[0]-P0[0];
                              var uy = P2[1]-P0[1];
                              var uz = P2[2]-P0[2];

                              var vx = P1[0]-P0[0];
                              var vy = P1[1]-P0[1];
                              var vz = P1[2]-P0[2];

                              // cross product n = u x v
                              var nx = uy*vz-uz*vy;
                              var ny = uz*vx-ux*vz;
                              var nz = ux*vy-uy*vx;
                              // normalize n (including cartesian scaled linewidth)
                              var leninv = w/Math.sqrt(nx*nx+ny*ny+nz*nz);
                              nx = nx*leninv;
                              ny = ny*leninv;
                              nz = nz*leninv;

                              var P00 = [P0[0]+nx, P0[1]+ny, P0[2]+nz];
                              var P10 = [P1[0]+nx, P1[1]+ny, P1[2]+nz];
                              var P20 = [P2[0]+nx, P2[1]+ny, P2[2]+nz];
                              var P30 = [P3[0]+nx, P3[1]+ny, P3[2]+nz];

                              var P01 = [P0[0]-nx, P0[1]-ny, P0[2]-nz];
                              var P11 = [P1[0]-nx, P1[1]-ny, P1[2]-nz];
                              var P21 = [P2[0]-nx, P2[1]-ny, P2[2]-nz];
                              var P31 = [P3[0]-nx, P3[1]-ny, P3[2]-nz];

                              pointlist.push(P00[0]); pointlist.push(P00[1]); pointlist.push(P00[2]);
                              idx00 = idx; idx++;
                              pointlist.push(P10[0]); pointlist.push(P10[1]); pointlist.push(P10[2]);
                              idx10 = idx; idx++;
                              pointlist.push(P20[0]); pointlist.push(P20[1]); pointlist.push(P20[2]);
                              idx20 = idx; idx++;
                              pointlist.push(P30[0]); pointlist.push(P30[1]); pointlist.push(P30[2]);
                              idx30 = idx; idx++;

                              pointlist.push(P01[0]); pointlist.push(P01[1]); pointlist.push(P01[2]);
                              idx01 = idx; idx++;
                              pointlist.push(P11[0]); pointlist.push(P11[1]); pointlist.push(P11[2]);
                              idx11 = idx; idx++;
                              pointlist.push(P21[0]); pointlist.push(P21[1]); pointlist.push(P21[2]);
                              idx21 = idx; idx++;
                              pointlist.push(P31[0]); pointlist.push(P31[1]); pointlist.push(P31[2]);
                              idx31 = idx; idx++;

                              // Front:
                              indexlist.push(idx01); indexlist.push(idx11); indexlist.push(idx21);
                              indexlist.push(idx11); indexlist.push(idx31); indexlist.push(idx21);
                              // Back:
                              indexlist.push(idx00); indexlist.push(idx20); indexlist.push(idx10);
                              indexlist.push(idx10); indexlist.push(idx20); indexlist.push(idx30);
                              // Left:
                              indexlist.push(idx00); indexlist.push(idx10); indexlist.push(idx01);
                              indexlist.push(idx10); indexlist.push(idx11); indexlist.push(idx01);
                              // Right:
                              indexlist.push(idx20); indexlist.push(idx21); indexlist.push(idx31);
                              indexlist.push(idx30); indexlist.push(idx20); indexlist.push(idx31);
                              // Top:
                              indexlist.push(idx00); indexlist.push(idx01); indexlist.push(idx20);
                              indexlist.push(idx01); indexlist.push(idx21); indexlist.push(idx20);
                              // Bottom:
                              indexlist.push(idx10); indexlist.push(idx31); indexlist.push(idx11);
                              indexlist.push(idx10); indexlist.push(idx30); indexlist.push(idx31);

                              // fwd base points
                              P0 = P2;
                              P1 = P3;
                              // fwd indices
                              idx00 = idx01;
                              idx10 = idx11;
                              idx20 = idx21;
                              idx30 = idx31;

                           }

                           // generate pointlist (for p-shader)
                           for (var j=0;j<geopairs.length;j++)
                           {
                              var pt = geopairs[j];
                              pointlist.push(pt[0]); pointlist.push(pt[1]); pointlist.push(pt[2]);
                           }

                           /** @type {ObjectJSON} */
                           var object = {"VertexSemantic" : "", "Vertices" : null, "IndexSemantic":"", "Indices":null};
                           object["VertexSemantic"]  = "p";
                           object["IndexSemantic"] = "TRIANGLES";
                           object["Vertices"] = pointlist;
                           object["Indices"] = indexlist;

                           var engine = this._GetEngine();
                           var surface = new Surface(engine);

                           surface.CreateFromJSONObject(object, null, null, surface);

                           if (this.color.length == 4)
                           {
                              surface.solidcolor.Set(this.color[0],this.color[1],this.color[2],this.color[3]);
                           }
                           else if (this.color.length == 3)
                           {
                              surface.solidcolor.Set(this.color[0],this.color[1],this.color[2],1);
                           }

                           this.surfaces.push(surface);

                           bCreated = true;
                        }
                     }
                     else if (geometrytype == "MultiLineString")
                     {
                        ogError("MultiLineString is not yet supported")
                     }
                     else if (geometrytype == "Polygon")
                     {
                        ogError("Polygon is not yet supported")
                     }
                     else if (geometrytype == "MultiPolygon")
                     {
                        ogError("MultiPolygon is not yet supported")
                     }
                     else if (geometrytype == "Point")
                     {
                        ogError("Point is not yet supported")
                     }
                     else if (geometrytype == "MultiPoint")
                     {
                        ogError("MultiPoint is not yet supported")
                     }
                  }
               }
            }
         }
      }
   }
   else
   {
      // not yet supported...
   }

   if (bCreated)
   {
      var renderer = this._GetVectorRenderer();
      this.indexInRendererArray = renderer.AddVector(this.surfaces);
   }
}

//------------------------------------------------------------------------------
/**
 * @description Load surface-data from a JSON file.
 * @param {string} url the url to the JSON file.
 */
ogVector.prototype.LoadGeoJSON = function(url)
{
   if(url == null)
   {
      alert("invalid json-url");
      return;
   }
   this.jsonUrl=url;

   this.http=new window.XMLHttpRequest();
   this.http.open("GET",this.jsonUrl,true);
   //this.http.setRequestHeader("Cache-Control", "public");

   var me=this;
   this.http.onreadystatechange = function(){me._cbfjsondownload();};
   //this.http.onprogress = function(){me._cbfonprogress();}
   this.http.send();
}
//------------------------------------------------------------------------------

<|endoftext|>


<commit_before>'use strict';

const electron = require('electron');
const app = electron.app;  // Module to control application life.
const BrowserWindow = electron.BrowserWindow;  // Module to create native browser window.
var path = require('path');
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
var mainWindow = null;

// Quit when all windows are closed.
app.on('window-all-closed', function() {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform != 'darwin') {
    app.quit();
  }
});

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', function() {
  // Create the browser window.
  mainWindow = new BrowserWindow({width: 800, height: 600});

  // and load the index.html of the app.
  //var indexPath = 'file://' + __dirname + '/index.html';
  var indexPath = 'file://' + path.dirname(__dirname) + '/index.html';
  console.log("mainWindow.loadURL: " + indexPath);
  console.log("App path: " + app.getAppPath());

  mainWindow.loadURL(indexPath);

  // Open the DevTools.
  mainWindow.webContents.openDevTools();

  // Emitted when the window is closed.
  mainWindow.on('closed', function() {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
  });
});<commit_msg>correcting the initial windows size<commit_after>'use strict';

const electron = require('electron');
const app = electron.app;  // Module to control application life.
const BrowserWindow = electron.BrowserWindow;  // Module to create native browser window.
var path = require('path');
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
var mainWindow = null;

// Quit when all windows are closed.
app.on('window-all-closed', function() {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform != 'darwin') {
    app.quit();
  }
});

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', function() {
  // Create the browser window.
  mainWindow = new BrowserWindow({width: 1280, height: 768});

  // and load the index.html of the app.
  //var indexPath = 'file://' + __dirname + '/index.html';
  var indexPath = 'file://' + path.dirname(__dirname) + '/index.html';
  console.log("mainWindow.loadURL: " + indexPath);
  console.log("App path: " + app.getAppPath());

  mainWindow.loadURL(indexPath);

  // Open the DevTools.
  mainWindow.webContents.openDevTools();

  // Emitted when the window is closed.
  mainWindow.on('closed', function() {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
  });
});<|endoftext|>


<commit_before>define([
  './query_def'
],
function (queryDef) {
  'use strict';

  function ElasticQueryBuilder(options) {
    this.timeField = options.timeField;
    this.esVersion = options.esVersion;
  }

  ElasticQueryBuilder.prototype.getRangeFilter = function() {
    var filter = {};
    filter[this.timeField] = {
      gte: "$timeFrom",
      lte: "$timeTo",
      format: "epoch_millis",
    };

    return filter;
  };

  ElasticQueryBuilder.prototype.buildTermsAgg = function(aggDef, queryNode, target) {
    var metricRef, metric, y;
    queryNode.terms = { "field": aggDef.field };

    if (!aggDef.settings) {
      return queryNode;
    }

    queryNode.terms.size = parseInt(aggDef.settings.size, 10) === 0 ? 500 : parseInt(aggDef.settings.size, 10);
    if (aggDef.settings.orderBy !== void 0) {
      queryNode.terms.order = {};
      queryNode.terms.order[aggDef.settings.orderBy] = aggDef.settings.order;

      // if metric ref, look it up and add it to this agg level
      metricRef = parseInt(aggDef.settings.orderBy, 10);
      if (!isNaN(metricRef)) {
        for (y = 0; y < target.metrics.length; y++) {
          metric = target.metrics[y];
          if (metric.id === aggDef.settings.orderBy) {
            queryNode.aggs = {};
            queryNode.aggs[metric.id] = {};
            queryNode.aggs[metric.id][metric.type] = {field: metric.field};
            break;
          }
        }
      }
    }

    if (aggDef.settings.min_doc_count !== void 0) {
      queryNode.terms.min_doc_count = parseInt(aggDef.settings.min_doc_count, 10);
    }

    if (aggDef.settings.missing) {
      queryNode.terms.missing = aggDef.settings.missing;
    }

    return queryNode;
  };

  ElasticQueryBuilder.prototype.getDateHistogramAgg = function(aggDef) {
    var esAgg = {};
    var settings = aggDef.settings || {};
    esAgg.interval = settings.interval;
    esAgg.field = this.timeField;
    esAgg.min_doc_count = settings.min_doc_count || 0;
    esAgg.extended_bounds = {min: "$timeFrom", max: "$timeTo"};
    esAgg.format = "epoch_millis";

    if (esAgg.interval === 'auto') {
      esAgg.interval = "$__interval";
    }

    if (settings.missing) {
      esAgg.missing = settings.missing;
    }

    return esAgg;
  };

  ElasticQueryBuilder.prototype.getHistogramAgg = function(aggDef) {
    var esAgg = {};
    var settings = aggDef.settings || {};
    esAgg.interval = settings.interval;
    esAgg.field = aggDef.field;
    esAgg.min_doc_count = settings.min_doc_count || 0;

    if (settings.missing) {
      esAgg.missing = settings.missing;
    }
    return esAgg;
  };

  ElasticQueryBuilder.prototype.getFiltersAgg = function(aggDef) {
    var filterObj = {};
    for (var i = 0; i < aggDef.settings.filters.length; i++) {
      var query = aggDef.settings.filters[i].query;

      filterObj[query] = {
        query_string: {
          query: query,
          analyze_wildcard: true
        }
      };
    }

    return filterObj;
  };

  ElasticQueryBuilder.prototype.documentQuery = function(query) {
    query.size = 500;
    query.sort = {};
    query.sort[this.timeField] = {order: 'desc', unmapped_type: 'boolean'};

    // fields field not supported on ES 5.x
    if (this.esVersion < 5) {
      query.fields = ["*", "_source"];
    }

    query.script_fields = {},
    query.fielddata_fields = [this.timeField];
    return query;
  };

  ElasticQueryBuilder.prototype.addAdhocFilters = function(query, adhocFilters) {
    if (!adhocFilters) {
      return;
    }

    var i, filter, condition;
    for (i = 0; i < adhocFilters.length; i++) {
      filter = adhocFilters[i];
      condition = {};
      condition[filter.key] = filter.value;
      switch(filter.operator){
        case "=":
          query.query.bool.filter.push({"term": condition});
          break;
        case "!=":
          query.query.bool.filter.push({"bool": {"must_not": {"term": condition}}});
          break;
        case "<":
          condition[filter.key] = {"lt": filter.value};
          query.query.bool.filter.push({"range": condition});
          break;
        case ">":
          condition[filter.key] = {"gt": filter.value};
          query.query.bool.filter.push({"range": condition});
          break;
        case "=~":
          query.query.bool.filter.push({"regexp": condition});
          break;
        case "!~":
          query.query.bool.filter.push({"bool": {"must_not": {"regexp": condition}}});
          break;
      }
    }
  };

  ElasticQueryBuilder.prototype.build = function(target, adhocFilters, queryString) {
    // make sure query has defaults;
    target.metrics = target.metrics || [{ type: 'count', id: '1' }];
    target.dsType = 'elasticsearch';
    target.bucketAggs = target.bucketAggs || [{type: 'date_histogram', id: '2', settings: {interval: 'auto'}}];
    target.timeField =  this.timeField;

    var i, nestedAggs, metric;
    var query = {
      "size": 0,
      "query": {
        "bool": {
          "filter": [
            {"range": this.getRangeFilter()},
            {
              "query_string": {
                "analyze_wildcard": true,
                "query": queryString,
              }
            }
          ]
        }
      }
    };

    this.addAdhocFilters(query, adhocFilters);

    // handle document query
    if (target.bucketAggs.length === 0) {
      metric = target.metrics[0];
      if (metric && metric.type !== 'raw_document') {
        throw {message: 'Invalid query'};
      }
      return this.documentQuery(query, target);
    }

    nestedAggs = query;

    for (i = 0; i < target.bucketAggs.length; i++) {
      var aggDef = target.bucketAggs[i];
      var esAgg = {};

      switch(aggDef.type) {
        case 'date_histogram': {
          esAgg["date_histogram"] = this.getDateHistogramAgg(aggDef);
          break;
        }
        case 'histogram': {
          esAgg["histogram"] = this.getHistogramAgg(aggDef);
          break;
        }
        case 'filters': {
          esAgg["filters"] = {filters: this.getFiltersAgg(aggDef)};
          break;
        }
        case 'terms': {
          this.buildTermsAgg(aggDef, esAgg, target);
          break;
        }
        case 'geohash_grid': {
          esAgg['geohash_grid'] = {field: aggDef.field, precision: aggDef.settings.precision};
          break;
        }
      }

      nestedAggs.aggs = nestedAggs.aggs || {};
      nestedAggs.aggs[aggDef.id] = esAgg;
      nestedAggs = esAgg;
    }

    nestedAggs.aggs = {};

    for (i = 0; i < target.metrics.length; i++) {
      metric = target.metrics[i];
      if (metric.type === 'count') {
        continue;
      }

      var aggField = {};
      var metricAgg = null;

      if (queryDef.isPipelineAgg(metric.type)) {
        if (metric.pipelineAgg && /^\d*$/.test(metric.pipelineAgg)) {
          metricAgg = { buckets_path: metric.pipelineAgg };
        } else {
          continue;
        }
      } else {
        metricAgg = {field: metric.field};
      }

      for (var prop in metric.settings) {
        if (metric.settings.hasOwnProperty(prop) && metric.settings[prop] !== null) {
          metricAgg[prop] = metric.settings[prop];
        }
      }

      aggField[metric.type] = metricAgg;
      nestedAggs.aggs[metric.id] = aggField;
    }

    return query;
  };

  ElasticQueryBuilder.prototype.getTermsQuery = function(queryDef) {
    var query = {
      "size": 0,
      "query": {
        "bool": {
          "filter": [{"range": this.getRangeFilter()}]
        }
      }
    };

    if (queryDef.query) {
      query.query.bool.filter.push({
        "query_string": {
          "analyze_wildcard": true,
          "query": queryDef.query,
        }
      });
    }

    var size = 500;
    if (queryDef.size) {
      size = queryDef.size;
    }

    query.aggs =  {
      "1": {
        "terms": {
          "field": queryDef.field,
          "size": size,
          "order": {
            "_term": "asc"
          }
        },
      }
    };
    return query;
  };

  return ElasticQueryBuilder;
});
<commit_msg>Rename fielddata_fields to docvalue_fields (#8317)<commit_after>define([
  './query_def'
],
function (queryDef) {
  'use strict';

  function ElasticQueryBuilder(options) {
    this.timeField = options.timeField;
    this.esVersion = options.esVersion;
  }

  ElasticQueryBuilder.prototype.getRangeFilter = function() {
    var filter = {};
    filter[this.timeField] = {
      gte: "$timeFrom",
      lte: "$timeTo",
      format: "epoch_millis",
    };

    return filter;
  };

  ElasticQueryBuilder.prototype.buildTermsAgg = function(aggDef, queryNode, target) {
    var metricRef, metric, y;
    queryNode.terms = { "field": aggDef.field };

    if (!aggDef.settings) {
      return queryNode;
    }

    queryNode.terms.size = parseInt(aggDef.settings.size, 10) === 0 ? 500 : parseInt(aggDef.settings.size, 10);
    if (aggDef.settings.orderBy !== void 0) {
      queryNode.terms.order = {};
      queryNode.terms.order[aggDef.settings.orderBy] = aggDef.settings.order;

      // if metric ref, look it up and add it to this agg level
      metricRef = parseInt(aggDef.settings.orderBy, 10);
      if (!isNaN(metricRef)) {
        for (y = 0; y < target.metrics.length; y++) {
          metric = target.metrics[y];
          if (metric.id === aggDef.settings.orderBy) {
            queryNode.aggs = {};
            queryNode.aggs[metric.id] = {};
            queryNode.aggs[metric.id][metric.type] = {field: metric.field};
            break;
          }
        }
      }
    }

    if (aggDef.settings.min_doc_count !== void 0) {
      queryNode.terms.min_doc_count = parseInt(aggDef.settings.min_doc_count, 10);
    }

    if (aggDef.settings.missing) {
      queryNode.terms.missing = aggDef.settings.missing;
    }

    return queryNode;
  };

  ElasticQueryBuilder.prototype.getDateHistogramAgg = function(aggDef) {
    var esAgg = {};
    var settings = aggDef.settings || {};
    esAgg.interval = settings.interval;
    esAgg.field = this.timeField;
    esAgg.min_doc_count = settings.min_doc_count || 0;
    esAgg.extended_bounds = {min: "$timeFrom", max: "$timeTo"};
    esAgg.format = "epoch_millis";

    if (esAgg.interval === 'auto') {
      esAgg.interval = "$__interval";
    }

    if (settings.missing) {
      esAgg.missing = settings.missing;
    }

    return esAgg;
  };

  ElasticQueryBuilder.prototype.getHistogramAgg = function(aggDef) {
    var esAgg = {};
    var settings = aggDef.settings || {};
    esAgg.interval = settings.interval;
    esAgg.field = aggDef.field;
    esAgg.min_doc_count = settings.min_doc_count || 0;

    if (settings.missing) {
      esAgg.missing = settings.missing;
    }
    return esAgg;
  };

  ElasticQueryBuilder.prototype.getFiltersAgg = function(aggDef) {
    var filterObj = {};
    for (var i = 0; i < aggDef.settings.filters.length; i++) {
      var query = aggDef.settings.filters[i].query;

      filterObj[query] = {
        query_string: {
          query: query,
          analyze_wildcard: true
        }
      };
    }

    return filterObj;
  };

  ElasticQueryBuilder.prototype.documentQuery = function(query) {
    query.size = 500;
    query.sort = {};
    query.sort[this.timeField] = {order: 'desc', unmapped_type: 'boolean'};

    // fields field not supported on ES 5.x
    if (this.esVersion < 5) {
      query.fields = ["*", "_source"];
    }

    query.script_fields = {},
    query.docvalue_fields = [this.timeField];
    return query;
  };

  ElasticQueryBuilder.prototype.addAdhocFilters = function(query, adhocFilters) {
    if (!adhocFilters) {
      return;
    }

    var i, filter, condition;
    for (i = 0; i < adhocFilters.length; i++) {
      filter = adhocFilters[i];
      condition = {};
      condition[filter.key] = filter.value;
      switch(filter.operator){
        case "=":
          query.query.bool.filter.push({"term": condition});
          break;
        case "!=":
          query.query.bool.filter.push({"bool": {"must_not": {"term": condition}}});
          break;
        case "<":
          condition[filter.key] = {"lt": filter.value};
          query.query.bool.filter.push({"range": condition});
          break;
        case ">":
          condition[filter.key] = {"gt": filter.value};
          query.query.bool.filter.push({"range": condition});
          break;
        case "=~":
          query.query.bool.filter.push({"regexp": condition});
          break;
        case "!~":
          query.query.bool.filter.push({"bool": {"must_not": {"regexp": condition}}});
          break;
      }
    }
  };

  ElasticQueryBuilder.prototype.build = function(target, adhocFilters, queryString) {
    // make sure query has defaults;
    target.metrics = target.metrics || [{ type: 'count', id: '1' }];
    target.dsType = 'elasticsearch';
    target.bucketAggs = target.bucketAggs || [{type: 'date_histogram', id: '2', settings: {interval: 'auto'}}];
    target.timeField =  this.timeField;

    var i, nestedAggs, metric;
    var query = {
      "size": 0,
      "query": {
        "bool": {
          "filter": [
            {"range": this.getRangeFilter()},
            {
              "query_string": {
                "analyze_wildcard": true,
                "query": queryString,
              }
            }
          ]
        }
      }
    };

    this.addAdhocFilters(query, adhocFilters);

    // handle document query
    if (target.bucketAggs.length === 0) {
      metric = target.metrics[0];
      if (metric && metric.type !== 'raw_document') {
        throw {message: 'Invalid query'};
      }
      return this.documentQuery(query, target);
    }

    nestedAggs = query;

    for (i = 0; i < target.bucketAggs.length; i++) {
      var aggDef = target.bucketAggs[i];
      var esAgg = {};

      switch(aggDef.type) {
        case 'date_histogram': {
          esAgg["date_histogram"] = this.getDateHistogramAgg(aggDef);
          break;
        }
        case 'histogram': {
          esAgg["histogram"] = this.getHistogramAgg(aggDef);
          break;
        }
        case 'filters': {
          esAgg["filters"] = {filters: this.getFiltersAgg(aggDef)};
          break;
        }
        case 'terms': {
          this.buildTermsAgg(aggDef, esAgg, target);
          break;
        }
        case 'geohash_grid': {
          esAgg['geohash_grid'] = {field: aggDef.field, precision: aggDef.settings.precision};
          break;
        }
      }

      nestedAggs.aggs = nestedAggs.aggs || {};
      nestedAggs.aggs[aggDef.id] = esAgg;
      nestedAggs = esAgg;
    }

    nestedAggs.aggs = {};

    for (i = 0; i < target.metrics.length; i++) {
      metric = target.metrics[i];
      if (metric.type === 'count') {
        continue;
      }

      var aggField = {};
      var metricAgg = null;

      if (queryDef.isPipelineAgg(metric.type)) {
        if (metric.pipelineAgg && /^\d*$/.test(metric.pipelineAgg)) {
          metricAgg = { buckets_path: metric.pipelineAgg };
        } else {
          continue;
        }
      } else {
        metricAgg = {field: metric.field};
      }

      for (var prop in metric.settings) {
        if (metric.settings.hasOwnProperty(prop) && metric.settings[prop] !== null) {
          metricAgg[prop] = metric.settings[prop];
        }
      }

      aggField[metric.type] = metricAgg;
      nestedAggs.aggs[metric.id] = aggField;
    }

    return query;
  };

  ElasticQueryBuilder.prototype.getTermsQuery = function(queryDef) {
    var query = {
      "size": 0,
      "query": {
        "bool": {
          "filter": [{"range": this.getRangeFilter()}]
        }
      }
    };

    if (queryDef.query) {
      query.query.bool.filter.push({
        "query_string": {
          "analyze_wildcard": true,
          "query": queryDef.query,
        }
      });
    }

    var size = 500;
    if (queryDef.size) {
      size = queryDef.size;
    }

    query.aggs =  {
      "1": {
        "terms": {
          "field": queryDef.field,
          "size": size,
          "order": {
            "_term": "asc"
          }
        },
      }
    };
    return query;
  };

  return ElasticQueryBuilder;
});
<|endoftext|>


<commit_before>HandsomeTrello.api = {
  request: function (type, url, data, callback) {
    var self = this;

    var xhttp = new XMLHttpRequest();

    if (typeof data !== 'object') {
      data = {};
    }

    if (type.toLowerCase() !== 'get') {
      data.token = self.base.getCookie('token');
    } else if (Object.keys(data).length) {
      url += '?' + self.base.generateParamsStringFromObject(data);

      data = {};
    }

    xhttp.open(type.toUpperCase(), url, true);
    xhttp.setRequestHeader('Content-Type', 'application/json');
    xhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

    xhttp.onreadystatechange = function () {
      if (xhttp.readyState === 4 && xhttp.status === 200 && typeof callback === 'function' && self.base.isJSONString(xhttp.responseText)) {
        callback(JSON.parse(xhttp.responseText));
      }
    };

    xhttp.send(JSON.stringify(data));
  },
  board: {
    get: function (boardId, callback) {
      var self = this.base;

      self.request('get', 'https://trello.com/1/Boards/' + boardId, {
        lists: 'open',
        cards: 'all',
        card_checklists: 'all',
        members: 'all'
      }, callback);
    }
  },
  card: {
    get: function (cardId, callback) {
      var self = this.base;

      self.request('get', 'https://trello.com/1/Cards/' + cardId, {
        checklists: 'all'
      }, callback);
    },
    create: function (title, columnId, pos, callback) {
      var self = this.base;

      var data = {
        name: title,
        pos: pos,
        dateLastActivity: Date.now(),
        closed: false,
        idLabels: [],
        idMembers: [],
        idBoard: self.base.data.boardId,
        idList: columnId
      };

      self.request('post', '/1/cards', data, callback);
    }
  },
  checklist: {
    getByCardId: function (cardId, callback) {
      var self = this.base;

      self.request('get', '/1/cards/' + cardId + '/checklists', {}, callback);
    },
    get: function (checklistId, callback) {
      var self = this.base;

      self.request('get', '/1/checklists/' + checklistId, {}, callback);
    },
    create: function (cardId, name, pos, callback) {
      var self = this.base;

      var data = {
        idCard: cardId,
        name: name,
        pos: pos
      };

      self.request('post', '/1/checklists', data, callback);
    },
    remove: function (checklistId, callback) {
      var self = this.base;

      self.request('delete', '/1/checklists/' + checklistId, {}, callback);
    },
    addItem: function (checklistId, name, pos, callback) {
      var self = this.base;

      var data = {
        name: name,
        pos: pos
      };

      self.request('post', '/1/checklists/' + checklistId + '/checkItems', data, callback);
    },
    deleteItem: function (checklistId, checkItemId, callback) {
      var self = this.base;

      var data = {
        idCheckItem: checkItemId
      };

      self.request('delete', '/1/checklists/' + checklistId + '/checkItems/' + checkItemId, data, callback);
    },
    posItem: function (cardId, checklistId, checkItemId, pos, callback) {
      var self = this.base;

      var data = {
        idChecklist: checklistId,
        idCheckItem: checkItemId,
        value: pos
      };

      self.request('put', '/1/cards/' + cardId + '/checklist/' + checklistId + '/checkItem/' + checkItemId + '/pos', data, callback);
    }
  },
  member: {
    get: function (username, data, callback) {
      var self = this.base;

      self.request('get', '/1/members/' + username, data, callback);
    }
  }
};
<commit_msg>Rename api-calling methods<commit_after>HandsomeTrello.api = {
  request: function (type, url, data, callback) {
    var self = this;

    var xhttp = new XMLHttpRequest();

    if (typeof data !== 'object') {
      data = {};
    }

    if (type.toLowerCase() !== 'get') {
      data.token = self.base.getCookie('token');
    } else if (Object.keys(data).length) {
      url += '?' + self.base.generateParamsStringFromObject(data);

      data = {};
    }

    xhttp.open(type.toUpperCase(), url, true);
    xhttp.setRequestHeader('Content-Type', 'application/json');
    xhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

    xhttp.onreadystatechange = function () {
      if (xhttp.readyState === 4 && xhttp.status === 200 && typeof callback === 'function' && self.base.isJSONString(xhttp.responseText)) {
        callback(JSON.parse(xhttp.responseText));
      }
    };

    xhttp.send(JSON.stringify(data));
  },
  board: {
    get: function (boardId, callback) {
      var self = this.base;

      self.request('get', 'https://trello.com/1/boards/' + boardId, {
        lists: 'open',
        cards: 'all',
        card_checklists: 'all',
        members: 'all'
      }, callback);
    }
  },
  card: {
    get: function (cardId, callback) {
      var self = this.base;

      self.request('get', 'https://trello.com/1/cards/' + cardId, {
        checklists: 'all'
      }, callback);
    },
    create: function (title, columnId, pos, callback) {
      var self = this.base;

      var data = {
        name: title,
        pos: pos,
        dateLastActivity: Date.now(),
        closed: false,
        idLabels: [],
        idMembers: [],
        idBoard: self.base.data.boardId,
        idList: columnId
      };

      self.request('post', '/1/cards', data, callback);
    }
  },
  checklist: {
    getByCardId: function (cardId, callback) {
      var self = this.base;

      self.request('get', '/1/cards/' + cardId + '/checklists', {}, callback);
    },
    get: function (checklistId, callback) {
      var self = this.base;

      self.request('get', '/1/checklists/' + checklistId, {}, callback);
    },
    create: function (cardId, name, pos, callback) {
      var self = this.base;

      var data = {
        idCard: cardId,
        name: name,
        pos: pos
      };

      self.request('post', '/1/checklists', data, callback);
    },
    remove: function (checklistId, callback) {
      var self = this.base;

      self.request('delete', '/1/checklists/' + checklistId, {}, callback);
    },
    addItem: function (checklistId, name, pos, callback) {
      var self = this.base;

      var data = {
        name: name,
        pos: pos
      };

      self.request('post', '/1/checklists/' + checklistId + '/checkItems', data, callback);
    },
    deleteItem: function (checklistId, checkItemId, callback) {
      var self = this.base;

      var data = {
        idCheckItem: checkItemId
      };

      self.request('delete', '/1/checklists/' + checklistId + '/checkItems/' + checkItemId, data, callback);
    },
    posItem: function (cardId, checklistId, checkItemId, pos, callback) {
      var self = this.base;

      var data = {
        idChecklist: checklistId,
        idCheckItem: checkItemId,
        value: pos
      };

      self.request('put', '/1/cards/' + cardId + '/checklist/' + checklistId + '/checkItem/' + checkItemId + '/pos', data, callback);
    }
  },
  member: {
    get: function (username, data, callback) {
      var self = this.base;

      self.request('get', '/1/members/' + username, data, callback);
    }
  }
};
<|endoftext|>


<commit_before>require.config({
  baseUrl: 'src/js',
  paths: {
    jquery: '//code.jquery.com/jquery-2.1.4',
    bootstrap: '//netdna.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap',
    jui: '//rawgit.com/seogi1004/jui/develop/dist/jui'
  },
  shim: {
    bootstrap: ['jquery'],
    jui : ['jquery']
  },
  packages: [{
    name: 'summernote',
    main: 'summernote',
    location: './'
  }]
});

require([
  'jquery',
  'summernote'
], function ($) {
  // editor type setting
  switch ($('script[data-editor-type]').data('editor-type')) {
    case 'lite':
      require(['summernote/lite/settings'], function (lite) {
        $.summernote = $.extend($.summernote, lite);
        // initialize summernote
        $('.summernote').summernote({
          height: 300
        });
      });
      break;
    case 'bs3':
      require(['bootstrap', 'summernote/bs3/settings'], function (bootstrap, bs3) {
        $.summernote = $.extend($.summernote, bs3);
        // initialize summernote
        $('.summernote').summernote({
          height: 300
        });
      });
      break;
    case 'jui':
      require(['jui', 'summernote/jui/settings'], function (jui, settings) {
        $.summernote = $.extend($.summernote, settings);
        // initialize summernote
        $('.summernote').summernote({
          height: 300
        });
      });
      break;
  }
});
<commit_msg>Refactor remove duplicated init code.<commit_after>require.config({
  baseUrl: 'src/js',
  paths: {
    jquery: '//code.jquery.com/jquery-2.1.4',
    bootstrap: '//netdna.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap',
    jui: '//rawgit.com/seogi1004/jui/develop/dist/jui'
  },
  shim: {
    bootstrap: ['jquery'],
    jui : ['jquery']
  },
  packages: [{
    name: 'summernote',
    main: 'summernote',
    location: './'
  }]
});

require([
  'jquery',
  'summernote'
], function ($) {
  var requireByPromise = function (paths) {
    return $.Deferred(function (deferred) {
      require(paths, function () {
        deferred.resolve.apply(this, arguments);
      });
    });
  };

  var promise = $.Deferred();
  // editor type setting
  switch ($('script[data-editor-type]').data('editor-type')) {
    case 'lite':
      promise = requireByPromise(['summernote/lite/settings']).then(function (lite) {
        $.summernote = $.extend($.summernote, lite);
      });
      break;
    case 'bs3':
      promise = requireByPromise(['bootstrap', 'summernote/bs3/settings']).then(function (bootstrap, bs3) {
        $.summernote = $.extend($.summernote, bs3);
      });
      break;
    case 'jui':
      promise = requireByPromise(['jui', 'summernote/jui/settings']).then(function (j, jui) {
        $.summernote = $.extend($.summernote, jui);
      });
      break;
  }

  promise.then(function () {
    // initialize summernote
    $('.summernote').summernote({
      height: 300
    });
  });
});
<|endoftext|>