/**
 * Copyright (c) 2014 Petka Antonov
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:</p>
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 * 
 */
"use strict";
module.exports = function(Promise, INTERNAL) {
    var util = require("./util.js");
    var canAttach = require("./errors.js").canAttach;
    var errorObj = util.errorObj;
    var isObject = util.isObject;

    function getThen(obj) {
        try {
            return obj.then;
        }
        catch(e) {
            errorObj.e = e;
            return errorObj;
        }
    }

    function Promise$_Cast(obj, caller, originalPromise) {
        if (isObject(obj)) {
            if (obj instanceof Promise) {
                return obj;
            }
            else if (isAnyBluebirdPromise(obj)) {
                var ret = new Promise(INTERNAL);
                ret._setTrace(caller, void 0);
                obj._then(
                    ret._fulfillUnchecked,
                    ret._rejectUncheckedCheckError,
                    ret._progressUnchecked,
                    ret,
                    null,
                    void 0
                );
                ret._setFollowing();
                return ret;
            }
            var then = getThen(obj);
            if (then === errorObj) {
                caller = typeof caller === "function" ? caller : Promise$_Cast;
                if (originalPromise !== void 0 && canAttach(then.e)) {
                    originalPromise._attachExtraTrace(then.e);
                }
                return Promise.reject(then.e, caller);
            }
            else if (typeof then === "function") {
                caller = typeof caller === "function" ? caller : Promise$_Cast;
                return Promise$_doThenable(obj, then, caller, originalPromise);
            }
        }
        return obj;
    }

    var hasProp = {}.hasOwnProperty;
    function isAnyBluebirdPromise(obj) {
        return hasProp.call(obj, "_promise0");
    }

    function Promise$_doThenable(x, then, caller, originalPromise) {
        var resolver = Promise.defer(caller);
        var called = false;
        try {
            then.call(
                x,
                Promise$_resolveFromThenable,
                Promise$_rejectFromThenable,
                Promise$_progressFromThenable
            );
        }
        catch(e) {
            if (!called) {
                called = true;
                var trace = canAttach(e) ? e : new Error(e + "");
                if (originalPromise !== void 0) {
                    originalPromise._attachExtraTrace(trace);
                }
                resolver.promise._reject(e, trace);
            }
        }
        return resolver.promise;

        function Promise$_resolveFromThenable(y) {
            if (called) return;
            called = true;

            if (x === y) {
                var e = Promise._makeSelfResolutionError();
                if (originalPromise !== void 0) {
                    originalPromise._attachExtraTrace(e);
                }
                resolver.promise._reject(e, void 0);
                return;
            }
            resolver.resolve(y);
        }

        function Promise$_rejectFromThenable(r) {
            if (called) return;
            called = true;
            var trace = canAttach(r) ? r : new Error(r + "");
            if (originalPromise !== void 0) {
                originalPromise._attachExtraTrace(trace);
            }
            resolver.promise._reject(r, trace);
        }

        function Promise$_progressFromThenable(v) {
            if (called) return;
            var promise = resolver.promise;
            if (typeof promise._progress === "function") {
                promise._progress(v);
            }
        }
    }

    Promise._cast = Promise$_Cast;
};
