//
//
//
var WinkUtil = {
    isIE : navigator.userAgent.match(/MSIE/),

    inherits : function(subClass, baseClass, extend) {
        function inheritance() {}

        if (baseClass)
            inheritance.prototype = baseClass.prototype;

        subClass.prototype = new inheritance();
        subClass.prototype.constructor = subClass;

        if (baseClass) {
            subClass.baseConstructor = baseClass;
            subClass.superClass = baseClass.prototype;
        }

        if (extend) {
            for (var prop in extend) {
                subClass.prototype[prop] = extend[prop];
            } 
        }

        return subClass;
    },

    createElement : function(tag, attrs, children) {
        attrs = attrs || {}; 
        children = children || [];

        var el = document.createElement((WinkUtil.isIE && attrs.name) ? "<" + tag + " name=" + attrs.name + ">" : tag);

        for (var attr in attrs) {
            if (typeof attrs[attr] != 'function') {
                WinkUtil.setAttribute(attr, attrs[attr], el);
            }
        }

        for (var i = 0; i < children.length; i++) {
            if (children[i]) {
                if (typeof children[i] == 'string') 
                    children[i] = document.createTextNode(children[i]);
                else if (typeof children[i] == 'number') 
                    children[i] = document.createTextNode(children[i]);
                el.appendChild(children[i]);
            }
        }

        return el;
    },

    ieTransTable : {
      'class' : 'className',
      'for'   : 'htmlFor'
    },

    setAttribute : function(attr, aval, el) {
        if (WinkUtil.isIE) {
            var trans;

            if (trans = WinkUtil.ieTransTable[attr]) 
                el[trans] = aval;
            else if (attr == 'style') 
                el.style.cssText = aval;
            else if (attr.match(/^on/)) 
                el[attr] = new Function(aval);
            else 
                el.setAttribute(attr, aval);
        } else {
            el.setAttribute(attr, aval);
        }
    },

    tag : function(tname) {
        var attrs, children; 

        if (arguments.length > 1) {
            if (arguments[1].nodeName || typeof arguments[1] == "string") {
                children = [].slice.call(arguments, 1); 
            } else { 
                attrs = arguments[1]; 
                children = [].slice.call(arguments, 2); 
            };
        }

        return WinkUtil.createElement(tname, attrs, children);
    },

    removeAllChildren : function(e) {
        while (e.firstChild)
            e.removeChild(e.firstChild);
    }
};

//
//
//
var WinkSearch = function() {
    this.createHtml = true;
    this.target     = WinkSearch.LINK_TARGET_BLANK;
    this.results    = new Array();
    this.completeCB = null;
    this.suffix     = '';
}

WinkSearch.BASE   = false;
WinkSearch.APIKEY = false;
WinkSearch.cIndex = 1;
WinkSearch.context = new Array();
WinkSearch.HORIZONTAL_BRANDING = 2;

WinkSearch.LINK_TARGET_BLANK  = "_blank";
WinkSearch.LINK_TARGET_SELF   = "_self";
WinkSearch.LINK_TARGET_TOP    = "_top";
WinkSearch.LINK_TARGET_PARENT = "_parent";


//
//
//
WinkSearch.setOnLoadCallback = function(f) {
    var w = window;

    if (w.addEventListner)
        w.addEventListener("load", f, false);
    else if (w.attachEvent)
        w.attachEvent("onload", f);
    else
        w["onload"] = f;
};

WinkSearch.getBranding = function(el, o) {
    o = o || WinkSearch.HORIZONTAL_BRANDING;

    b = WinkUtil.tag('div', 
                                     WinkUtil.tag('div', { 'class': 'wink_powered' }, 
                                               'People Search powered by ',
                                               WinkUtil.tag('img', { src: 'http://wink.com/_/image/logo/winks.gif'})),
                                     WinkUtil.tag('div', { id: 'wink_results', 'class': 'wink_results' })
                             );

    if (el)
        el.appendChild(b);
        
    return b;
};

WinkSearch.makeRequest = function(obj, method, query) {
    ctx = WinkSearch.cIndex++;
    WinkSearch.context[ctx] = obj;

    query.callback    = 'WinkSearch.RawCompletion';
    query.id          = ctx;
    query.nocache     = (new Date).getTime();

    if (!WinkSearch.APIKEY || !WinkSearch.BASE) {
        var m, l = document.getElementsByTagName("script");
        if (l) {
            for (var i = 0; i < l.length; i++) {
                if (m = l[i].src.match(/^(http:\/\/[^\/]+)\/.*\/wps\.js\?.*key=([^&]+)$/)) {
                    if (!WinkSearch.BASE)
                        WinkSearch.BASE   = m[1];
                    if (!WinkSearch.APIKEY)
                        WinkSearch.APIKEY = m[2];
                    break;
                }
            }
        }
    }

    query.apikey      = WinkSearch.APIKEY;

    var q = '?method=' + method;

    for (var k in query) {
        if (typeof query[k] != 'function')
            q += '&' + encodeURIComponent(k) + '=' + encodeURIComponent(query[k]);
    }

    url = WinkSearch.BASE + '/services/sjson' + q;

    //
    // One cross site AjaxRequest...
    //
    var head = document.getElementsByTagName("head")[0];
    var stag = document.createElement('script');

    stag.type = "text/javascript";
    stag.charset = "utf-8";
    stag.src = url;

    var rfunc = function(v) {
                    if (v.parentNode)
                        v.parentNode.removeChild(v);
                    delete v;
                };

    if (navigator.product == "Gecko") {
        stag.onload = function() { rfunc(stag); };
    } else {
        stag.onreadystatechange = function(e) {
                                    evt = e ? e : window.event;
                                    el  = evt.target ? evt.target : evt.srcElement;
                                    if (el.readyState == 'loaded' || el.readyState == 'complete')
                                        rfunc(stag); 
                                };
    }

    head.appendChild(stag); 
};

WinkSearch.RawCompletion = function(ctx, res, code, emsg, ecode) {
    ctx = ctx ? parseInt(ctx) : 0;

    if (code == 200) {
        o = WinkSearch.context[ctx];
        WinkSearch.context[ctx] = null;
        if (o)
            o.onSearchComplete(res, code, emsg, ecode);
    } else {
        alert(emsg);
    }
};

WinkUtil.inherits(WinkSearch, null, {
    createResultHtml: function(res) {
    },

    setLinkTarget: function(t) {
        this.target = t;
    },

    onSearchComplete: function(res) {
        if (res) {
            this.results = res.results;
        } else {
            this.results = new Array();
        }

        if (this.createHtml)
            this.createResultHtml(this.results);
        
        if (this.completeCB) 
            this.completeCB.method.apply(this.completeCB.obj, this.completeCB.args);
    },

    execute: function(q) {
    },

    doExecute: function(m, q) {
        if (navigator.appVersion.indexOf("MSIE 6.0") > 0) {
            setTimeout(function() { WinkSearch.makeRequest(this, m, q) }, 0);
        } else {
            WinkSearch.makeRequest(this, m, q);
        }
    },

    clearResults: function() {
        // TODO
        this.results = new Array();
    },

    setUserDefinedClassSuffix: function(suf) {
        this.suffix = suf ? ('-' + suf) : '';
    },

    setSearchCompleteCallback: function(obj, method, args) {
        this.completeCB = {
                                'obj': obj,
                                'method': method,
                                'args': args
                          };
    },

    setNoHtmlGeneration: function() {
        this.createHtml = false;
    }
});

//
//
//
var WinkSearchControl = function() {  
    this.searchForm = null;
    this.completeCB = null;
    this.startingCB = null;
    this.searcher   = new WinkPeopleSearch();
};

WinkUtil.inherits(WinkSearchControl, null, {
    draw: function(block) {
        if (!block)
            return;

        this.searchForm = new WinkSearchForm();
        this.searchForm.draw(block);

        this.searchForm.setOnSubmitCallback(this, WinkSearchControl.prototype.submit);
        this.searchForm.setOnClearCallback(this, WinkSearchControl.prototype.clearAllResults);
    },

    execute: function(q) {
        if (this.searchForm) {
            if (!q) {
                q = this.searchForm.getQuery();
            } else {
                this.searchForm.setQuery(q);
            }
        }

        if (navigator.appVersion.indexOf("MSIE 6.0") > 0) {
            setTimeout(function() { WinkSearch.makeRequest(this, 'wink.search.people', q) }, 0);
        } else {
            WinkSearch.makeRequest(this, 'wink.search.people', q);
        }

        if (this.staringCB)
            this.staringCB.method.apply(this.completeCB.obj, this.completeCB.args);
    },

    onSearchComplete: function(res) {
        this.searcher.onSearchComplete(res);

        if (this.completeCB)
            this.completeCB.method.apply(this.completeCB.obj, this.completeCB.args);

        if (this.searchForm)
            this.searchForm.onSearchComplete(this.searcher);
    },

    clearAllResults: function() {
        this.searcher.clearResults();

        if (this.searchForm) 
            this.searchForm.clearResults();
    },

    setSearchStartingCallback : function(object, method) {
        this.startingCB = {
                                'obj': obj,
                                'method': method,
                                'args': [].slice.call(arguments, 2)
                          };
    },

    setSearchCompleteCallback : function(object, method) {
        this.completeCB = {
                                'obj': obj,
                                'method': method,
                                'args': [].slice.call(arguments, 2)
                          };
    },

    submit: function() {
        this.execute();
    },

    cancelSearch: function() {
        for (var i = 0; i < WinkSearch.context.length; i++) {
            WinkSearch.context[i] = null;
        }
    }
});

//
//
//
WinkSearchForm = function(ec, el) { 
    this.enableClear = ec;
    this.continer = el;
    this.clearCB = null;
    this.submitCB = null;
};

WinkUtil.inherits(WinkSearchForm, null, {
    draw: function(block) {
        form = WinkUtil.tag('form',
                          WinkUtil.tag('span', 
                            'Name: ',
                            WinkUtil.tag('input', { type: 'text', 'name': 'qn' })
                          ),
                          WinkUtil.tag('span', 
                            'Location: ',
                            WinkUtil.tag('input', { type: 'text', 'name': 'l' })
                          ),
                          WinkUtil.tag('span', 
                            'Interest: ',
                            WinkUtil.tag('input', { type: 'text', 'name': 'qi' })
                          ),
                          WinkUtil.tag('input', { 'type': 'submit', 'value': 'Search People'})
                       );

        form.onsubmit = function(o) { var obj = o; return function() { return obj.execute(); } }(this);

        block.appendChild(WinkUtil.tag('div', { 'class': 'wink_peoplesearch'}, form, WinkSearch.getBranding()));

        this.form = form;
    },

    onSearchComplete: function(searcher) {
        if (!searcher || !(block = document.getElementById('wink_results')))
            return;

        for (var i = 0; i < searcher.results.length; i++) {
            block.appendChild(searcher.results[i].html);
        }
    },

    execute: function(q) {
        if (q)
            this.setQuery(q);

        if (this.clearCB)
            this.clearCB.method.apply(this.submitCB.obj, [this.form]);

        if (this.submitCB)
            this.submitCB.method.apply(this.submitCB.obj, [this.form]);

        return false;
    },

    getQuery : function(q) {
        form = this.form;

        return {
                   qn : form.qn ? form.qn.value : '',
                   qi : form.qi ? form.qi.value : '',
                   l  : form.l  ? form.l.value : '' 
            };
    },

    setQuery : function(q) {
        if (this.form) {
            this.form.qn.value = q.qn ? q.qn : '';
            this.form.qi.value = q.qi ? q.qi : '';
            this.form.l.value  = q.l ? q.l : '';
        }
    },

    setOnSubmitCallback: function(obj, method) {
        this.submitCB = {
                                'obj': obj,
                                'method': method,
                                'args': [].slice.call(arguments, 2)
                          };
    },

    setOnClearCallback: function(obj, method) {
        this.clearCB = {
                                'obj': obj,
                                'method': method,
                                'args': [].slice.call(arguments, 2)
                          };
    },

    clearResults: function() {
        if (!(block = document.getElementById('wink_results')))
            return;

        WinkUtil.removeAllChildren(block);
    }
});

//
//
//

var WinkPeopleSearch = function() {
    WinkPeopleSearch.baseConstructor.call(this);
};

WinkUtil.inherits(WinkPeopleSearch, WinkSearch, {
    execute: function(q) {
        if (typeof q == 'string') {
            q = { qn: q };
        }
        this.doExecute('wink.search.people', q);
    },

    createResultHtml: function(results) {
        for (var i = 0; i < results.length; i++) {
            var item = results[i];

            places = WinkUtil.tag('div', { 'class': 'wink_places' }, 'Places: ');

            for (j = 0; j < item.places.length; j++) {
                p = item.places[j];

                places.appendChild(WinkUtil.tag('a', { target: this.target, href: p[1] }, p[0], (j == item.places.length - 1 ? null : ', ')));
                if (j == 4 && j != item.places.length - 1) {
                    places.appendChild(WinkUtil.tag('a', { target: this.target, href: item.places[0][1] }, 'more...'));
                    break;
                }
            }

            d = WinkUtil.tag('div', { 'class': 'wink_result' },
                         WinkUtil.tag('a', { target: this.target, href: item.click_url },
                          WinkUtil.tag('img', { src: item.image_url, 'class': 'wink_profile_iamge' })),
                        WinkUtil.tag('div', { 'class': 'wink_body' },
                         WinkUtil.tag('div', { 'class': 'wink_name' }, WinkUtil.tag('a', { target: this.target, href: item.click_url}, item.name),
                           ' ',
                           item.geo ? WinkUtil.tag('span', { 'class': 'wink_location' }, item.geo.title) : null 
                          ),
                         WinkUtil.tag('div', { 'class': 'wink_person_info' }, 
                           WinkUtil.tag('span', { 'class': 'wink_gender' }, item.gender),
                           ' ',
                           WinkUtil.tag('span', { 'class': 'wink_gender' }, item.age)
                          ),
                         WinkUtil.tag('div', { 'class': 'wink_summary' }, item.summary),
                         places
                         ),
                         WinkUtil.tag('div', { 'class': 'wink_result_break' })
                        );

            item.html = d;
        }
    }
});
