var mkt_yui_ws_app_id = "Qkkgf3DV34FxMqocdjStphcMOumd_m3YnVkQohoFSF_oYL6zJLQYQzmAFvchS0H2XQ--";

// all the pages within query_url domain.
function run_yui_pagedata(domain_url) {
    url = "http://search.yahooapis.com/SiteExplorerService/V1/pageData?"
    query = {'appid': mkt_yui_ws_app_id,
            'domain': 1,
            'results':100,
            'output':'json',
            'callback':'yui_callback_pagedata',
            'query':domain_url}

    url = url + make_query_string(query);
    run_json_call(url);
}

// callback function from YUI's pagedata.
function yui_callback_pagedata(json) {
    var rows = null;
    var results_count = 0;
    var set = json.ResultSet;

    if(set && set.totalResultsAvailable && set.Result) {
        results_count = set.totalResultsAvailable;
        rows = set.Result;

        if(!results_count || !rows) { return; }
    }

    // create yui tree.
    yui_tree.tree = new make_yui_tree();
    yui_tree.tree.build(rows);
}

// all the links that point to this link.
function run_yui_inlinks(link_url) {
    url = "http://search.yahooapis.com/SiteExplorerService/V1/inlinkData?"
    query = {'appid': mkt_yui_ws_app_id,
            'omit_inlinks': 'domain', // ignore links from own domain.
            'results':20,
            'output':'json',
            'callback':'yui_callback_inlinks',
            'query':link_url}

    url = url + make_query_string(query);
    run_json_call(url);
}

function yui_callback_inlinks(json) {
    var rows = null;
    var results_count = 0;
    var set = json.ResultSet;

    if(set && set.totalResultsAvailable && set.Result) {
        results_count = set.totalResultsAvailable;
        rows = set.Result;

        if(!results_count || !rows) { return; }
    }

    if(!yui_tree.tree) { return; }

    yui_tree.tree.child_node_loaded(rows);
}

// spelling suggestions
function run_spelling_suggestions(words) {
    url = "http://search.yahooapis.com/WebSearchService/V1/spellingSuggestion?"
    query = {'appid': mkt_yui_ws_app_id,
            'output':'json',
            'callback':'callback_spelling_suggestions',
            'query':words}

    url = url + make_query_string(query);
    run_json_call(url);
}

function callback_spelling_suggestions(json) {
    var set = json.ResultSet;

    if(set && set.Result) {
        var d = document.getElementById('search_results_for');
        var url = 'http://' + location.hostname + '/marketplace/search?tag=' + urlencode(set.Result);

        d.innerHTML += ' <b><span style="color:red;">Did you mean: </span>' + make_html_anchor(url, set.Result) + '<span style="color:red;">?</span></b>';
    }
}

// helper function to run JSONscriptRequest class.
function run_json_call(url) {
    var o = new neh_JSONscriptRequest(url);
    o.buildScriptTag();
    o.addScriptTag();
}


//////////////
// Animation for tag cloud
//////////////

// avoid waiting for <body onload="..."> to complete.
YAHOO.util.Event.onAvailable('cloud-btm', init_animate_tag_cloud);

var anim_tag = {
    initial_height: 0,
    is_open: true,
    anim: null, // current YAHOO.util.Anim object.
    padding_top:0,
    padding_bottom:0,
    margin_top:0,
    margin_bottom:0,

    nothing: null
};

function init_animate_tag_cloud() {
    var id = document.getElementById('cloud-btm');
    if(id) {
        anim_tag.initial_height = id.offsetHeight;
        anim_tag.padding_bottom = YAHOO.util.Dom.getStyle('cloud-btm', 'paddingBottom');
        anim_tag.padding_top = YAHOO.util.Dom.getStyle('cloud-btm', 'paddingTop');
        anim_tag.margin_bottom = YAHOO.util.Dom.getStyle('cloud-btm', 'marginBottom');
        anim_tag.margin_top = YAHOO.util.Dom.getStyle('cloud-btm', 'marginTop');
    }
}

function animate_tag_cloud(img_el) {
    check_stop_anim();

    if(anim_tag.is_open) { // means we are to close it now.
        YAHOO.util.Dom.setStyle('cloud-btm', 'paddingBottom', '0px');
        YAHOO.util.Dom.setStyle('cloud-btm', 'paddingTop', '0px');
        YAHOO.util.Dom.setStyle('cloud-btm', 'marginBottom', '0px');
        YAHOO.util.Dom.setStyle('cloud-btm', 'marginTop', '0px');

        img_el.src = "http://wptextads.s3.amazonaws.com/images/site/mkt/show.gif"; // set new state's icon. (open it)
        img_el.title = "Show tag cloud";
        var attributes = {height: {to: 0} };
    }else {
        YAHOO.util.Dom.setStyle('cloud-btm', 'paddingBottom', anim_tag.padding_bottom);
        YAHOO.util.Dom.setStyle('cloud-btm', 'paddingTop', anim_tag.padding_top);
        YAHOO.util.Dom.setStyle('cloud-btm', 'marginBottom', anim_tag.margin_bottom);
        YAHOO.util.Dom.setStyle('cloud-btm', 'marginTop', anim_tag.margin_top);

        img_el.src = "http://wptextads.s3.amazonaws.com/images/site/mkt/hide.gif";
        img_el.title = "Hide tag cloud";
        var attributes = {height: {to: anim_tag.initial_height} };
    }

    anim_tag.is_open = !anim_tag.is_open;

    anim_tag.anim = new YAHOO.util.Anim('cloud-btm', attributes, 0.5);
    anim_tag.anim.animate();

    function check_stop_anim() {
        if(anim_tag.anim && anim_tag.anim.isAnimated()) {
            anim_tag.anim.stop();
        }
    }
}


//////////
// YUI TreeView stuff
//////////

// shared data. cannot be in make_yui_tree as it fails to work properly.
// out of scope?
var yui_tree = {
    node_index: 0, // currently expanded node index.
    tree:null, // the make_yui_tree() object.

    nothing:null
};

make_yui_tree = function() {
    this.rows = null;
    this.tree = null;
    this.root = null;
    this.root_nodes = new Array();
}

make_yui_tree.prototype = {
    build: function(rows) {
        if(!rows || rows.length == 0) {
            return;
        }else {
            this.rows = rows;
        }

        // create new tree. 'tree_container' is id of a <div>.
        this.tree = new YAHOO.widget.TreeView("tree_container");

        //get root node for tree:
        this.root = this.tree.getRoot();

        for(var i = 0; i < this.rows.length; i++) {
            if(std_trim(this.rows[i].Title) == '') {
                continue;
            }

            var n = new YAHOO.widget.TextNode({label:this.rows[i].Title, href:this.rows[i].Url}, this.root, false);

            //turn dynamic loading on for root nodes only.
            n.setDynamicLoad(this.load_node_data, 1);

            this.root_nodes[n.index] = n;
        }

        this.tree.draw();
    },

    load_node_data: function(node, onCompleteCallback) {
        if(node.depth == 0) { // top-level node
            yui_tree.node_index = node.index;
            run_yui_inlinks(node.data.href);
        }

        // onCompleteCallback() is called in child_node_loaded.
    },

    // called by the yui_callback_inlinks().
    child_node_loaded: function(rows) {
        var node = this.root_nodes[yui_tree.node_index];

        if(rows && rows.length > 0) {
            for(var i = 0; i < rows.length; i++) {
                new YAHOO.widget.TextNode({label: rows[i].Title, href: rows[i].Url}, node, false);
            }
        }else {
            new YAHOO.widget.TextNode({label:"No data available"}, node, false);
        }

        // equivalent of onCompleteCallback().
        node.loadComplete();
    },

    do_nothing:function() {}
}





////////////////////////
// YUI AJAX stuff
// same domain only.
////////////////////////
var mkt_yui_ajax = {
    _conn: null,
    _json: null,

    handleSuccess: function(o) {
        this._json = null;

        if(o.responseText !== undefined){
            var arg = o.argument;
/* useful for debugging php errors in json output. */
//alert(o.responseText);

            try {
                eval("this._json=" + o.responseText);
                arg.on_success(this._json);
            }catch(e) {
                // technically not a failure, but simulate it since data is unusable.
                arg.on_failure();
            }
        }
    },

    handleFailure: function(o) {
        (o.status == -1) ? o.argument.on_abort() : o.argument.on_failure();
        this._json = null;
    },

    startRequest: function(url, query, get_or_post, obj) {
        // abort another this._conn if it is running.
        // this must happen before mkt_ajax_callback is set with the new obj.
        if(this._conn && !this.isCallCompleted()) {
            this._json = null;
            YAHOO.util.Connect.abort(this._conn, mkt_ajax_callback);
        }

        // this is returned in handleSuccess and handleFailure.
        // obj is an instance of mkt_argument_obj().
        mkt_ajax_callback['argument'] = obj;

        var query_str = make_query_string(query) + '&random=' + Math.random();

        if(get_or_post == "get") {
            this._conn = YAHOO.util.Connect.asyncRequest(get_or_post, url + "?" + query_str, mkt_ajax_callback);
        }else if(get_or_post == "post") {
            this._conn = YAHOO.util.Connect.asyncRequest(get_or_post, url, mkt_ajax_callback, query_str);
        }
    },

    isCallCompleted: function() {
        return YAHOO.util.Connect.isCallInProgress(this._conn) ? false : true;
    }
};

var mkt_ajax_callback =  {
    success: mkt_yui_ajax.handleSuccess,
    failure: mkt_yui_ajax.handleFailure,
    timeout: 30000, // 30s
    scope: mkt_yui_ajax
};


// passed into startRequest as the 'obj' argument.
// define prototype default functions that are called in mkt_yui_ajax. They should be overridden.
mkt_argument_obj = function() {
    this.element_id = null;
};

mkt_argument_obj.prototype = {
    on_success: function(json) { return },
    on_failure: function() { return },
    on_abort: function() { return }
};
