// assets/main.js

// --- GENERIC STUFF

var inIE = navigator.userAgent.indexOf("MSIE") >= 0 ;
var inOpera = navigator.userAgent.indexOf("Opera") >= 0 ;
var inNav = navigator.userAgent.indexOf("Gecko") >= 0 ;
var inSaf = navigator.userAgent.indexOf("Safari") >= 0;

function isObject(o){
    return typeof(o) == "object";
}

function isArray(a) {
    if ( ! isObject(a) )
        return false;

    if ( a.constructor == Array )
        return true;

    if ( a.constructor.toString().indexOf("Array") >= 0 )
        return true;

    if ( inSaf && typeof a.length == "number" )
        return true;

    return false;
}

// --- SW STUFF

SWDom = {
    findByClass : function( name , start ){
        start = start || document;

        return SWDom.findNodes( start , 
                          function( n ){
                              return n.className == name;
                          } );
    } ,
    
    findNodes : function( start , filter , lst ){
        lst = lst || [];
        if ( start && start.childNodes ){
            for ( var i=0; i<start.childNodes.length; i++ ){
                var n = start.childNodes[i];
                if ( filter( n ) )
                    lst.push( n );
                SWDom.findNodes( n , filter , lst );
            }
        }
        return lst;
    } ,

    setVisibility : function( node , type ){
        SWDom.setStyle( node , "visibility" , type );
    } ,

    setStyle : function( node , type , val ){
        
        if ( typeof node == "string" )
            node = document.getElementById( node );
        
        if ( ! node )
            return;
        
        node.style[type] = val;
    } ,

    large : function( node ){
        SWDom.setVisibility( node , "visible" );
    } ,

    small : function( node ){
        SWDom.setVisibility( node , "hidden" );
    } ,

    setLeft : function( node , pos ){
        SWDom.setStyle( node , "left" , pos );
    } ,

    get_elements : function(node) {
        var ret = [];
        for(var index = 0; index < node.childNodes.length; index++) {
            if ( node.childNodes[index].tagName == null)
                continue;
            ret.push(node.childNodes[index])
        }
        return ret;
    }


     
}

SearchPage = {
    enteredRow: null ,
    
    enterRow : function( num ){
        if ( this.shortListEnabled ) {
            var desc = 'lo_'+num+'_description';
            var hover = 'lo_'+num+'_sl';
            var d_elem = document.getElementById(desc);
            var h_elem = document.getElementById(hover);
            if ( h_elem ) {
                SWDom.small( d_elem );
                SWDom.large( h_elem );
            }
        }
    } ,

    leaveRow : function( num ){
        if (this.shortListEnabled) {
            var desc = 'lo_'+num+'_description';
            var hover = 'lo_'+num+'_sl';
            var d_elem = document.getElementById(desc);
            var h_elem = document.getElementById(hover);
            if ( h_elem ) {
                SWDom.small( h_elem );
                SWDom.large( d_elem );
            }
        }
    }, 
    
    shortListEnabled : true ,
    
    disableShortList : function() {
        for(var i = 1; i < 1000; i++) {
            if(! document.getElementById('lo_' + i)) {
                break;
            }
            this.leaveRow(i);
        }
        this.shortListEnabled = false;
    } ,
    
    enableShortList : function() {
        this.shortListEnabled = true;
    } ,
    
    replaceContent : function( data ){
        // THIS IS FOR SEARCH ONLY
        document.getElementById('results_only').innerHTML = data;
        // replace num results, etc.  The response contains hidden divs with the
        // new info.  Includes Case 3734: Update filters when search completes,
        // e.g. if user filtered by a store, there may be fewer brands available
        // in this one store. Or if user unfiltered by store there may be more
        // brands available.
        var elem_ids = ['num_results', 'page_title', 'price_low', 'price_high'];
        for (var i = 0; i < elem_ids.length; i++) {
            var new_elem = document.getElementById(elem_ids[i] + '_new');
            document.getElementById(elem_ids[i]).innerHTML = new_elem.innerHTML;
            
            // Avoid duplicate id's by deleting the new element and keeping the
            // original element with updated contents.
            //alert('delete ' + new_elem.id);
            new_elem.parentNode.removeChild(new_elem);
        }
    },
    
    update_canonical_url : function() {
        $('#link_to_this_page').html('<a href="'+$('#link_to_this_page_new').html()+'">'+$('#link_to_this_page_text').text()+'</a>');
    },
    
    getNewDataFromURL : function( url ){

        WAITER.render(document.body);
        WAITER.show();
        search_xhr = new XMLHttpRequest();
        search_xhr.onreadystatechange = SearchPage.dataHandler;
        search_xhr.open( "GET", url );
        search_xhr.send( null );
        // alert(url);
        // Add a listener that aborts the AJAX request before closing the dialog
        onYUIPanelClose(
            WAITER,
            function() {
                if (search_xhr) {
                    search_xhr.abort();
                    search_xhr = null;
                }
                
                WAITER.hide();
                
                // Snap right back to previous value without animating or
                // reloading search results (as we would if the user had
                // released the slider). You'd think we could unsubscribe /
                // resubscribe endUpdateUI() from the 'slideEnd' event, or that
                // the 'silent=true' parameter to setValues() would suppress the
                // 'slideEnd' event and not only the 'chang'e event, but when
                // ajdavis tried these techniques either the slider thumbs
                // didn't snap back, or endUpdateUI() was called when it
                // shouldn't have been.
                YAHOO.priceSlider.slider.slider_changing_programmatically += 2;
                YAHOO.priceSlider.slider.setValues(slider_min, slider_max, true, true, true);
                
                enable_filter_controls(true);
            },
            // Don't purge previous handlers: there's already a close-handler
            // that undoes the user's checking of a filter checkbox
            false
        );
    } ,
    
    dataHandler : function(){
        
        if ( this.readyState != 4 )
            return;
        WAITER.hide();
        enable_filter_controls(true);
        if (this.status == 200) {
            slider_min = YAHOO.priceSlider.slider.minVal;
            slider_max = YAHOO.priceSlider.slider.maxVal;
        }

        if( ! this.responseText )
            return;
        SearchPage.replaceContent(this.responseText);
        
        $('#results_only script').each(function() {
                eval(this.innerHTML);
            })
        
        search_xhr = null;
        $('.filter_container').redrawShadow();
    } ,
    
    /** Find checked filter controls (e.g., in the site filter which filters
     *  by store, or the brand filter) and request newly-filtered search
     *  results via AJAX
     */
    add_filter : function(){
        containers = {
            site: { id: 'site_list', filter_name: 'site_id' },
            brand: { id: 'brand_list', filter_name: 'brand' }
        }
        
        var params = SearchPage.filterParams;
        
        for (list_name in containers) {
            // If we're looking for site-filter controls, e.g., find inputs
            // whose id's start with "site_" within the "site_list" container
            if( ! document.getElementById(containers[list_name]['id'])) { 
              continue;
            }
            var input_id_pat = new RegExp('^' + list_name + '_');
            var inputs = document.getElementById(containers[list_name]['id']).getElementsByTagName('input');
            
            //alert('add_filter(): inputs = ' + inputs);
            
            var filter_name = containers[list_name]['filter_name'];
            
            // Clear previous search parameters
            delete params[filter_name];
            
            for( i = 0; i < inputs.length; i++ ) {
                if(inputs[i].id.match(input_id_pat) && inputs[i].checked) {
                    
                    //alert('add_filter(): found checked input with id ' + inputs[i].id + ', name ' + inputs[i].name);
                    
                    if(params[filter_name] && params[filter_name].length != 0) {
                        params[filter_name] += ',';
                    } else {
                        params[filter_name] = '';
                    }
                    
                    params[filter_name] += inputs[i].name;
                }
            }
        }
        SearchPage.updateFilters();
    } ,

    installPriceSlider : function( minPrice , maxPrice ){
        // Store current slider range for future
        slider_min = minPrice;
        slider_max = maxPrice;
        
        var price_range_pattern = /^(.*?)[\d,.]+(.*?)[\d,.]+(.*)$/;
        
        YAHOO.namespace("priceSlider");
        
        var Dom = YAHOO.util.Dom;
        
        var range = 180;
        var tickSize = 1;
        
        function positionToPrice( pos ) {
            return Math.floor( minPrice + ( ( pos / range ) * ( maxPrice - minPrice ) ) );
        }

        YAHOO.util.Event.onDOMReady(
            function () {
                var reportSpan = Dom.get("priceSlider_range");
                
                var slider = YAHOO.widget.Slider.getHorizDualSlider(
                    "priceSlider_bg", "priceSlider_min_thumb", "priceSlider_max_thumb",
                    range, tickSize);
                
                YAHOO.lang.augmentObject(slider, {
                    _highlight : Dom.get("priceSlider_highlight"),
                    
                    slider_changing_programmatically : 0,
                    
                    updateUI : function () {
                        var delta = this.maxVal - this.minVal;
                        Dom.setStyle(this._highlight,'left', (this.minVal + 12) + 'px');
                        Dom.setStyle(this._highlight,'width', Math.max(delta - 12,0) + 'px');
                        
                        var price_range_match = reportSpan.innerHTML.match(price_range_pattern);
                        reportSpan.innerHTML = price_range_match[1]
                            + positionToPrice( this.minVal ) + price_range_match[2]
                            + positionToPrice( this.maxVal ) + price_range_match[3];
                    },
                    
                    endUpdateUI : function () {
                        if (this.slider_changing_programmatically) {
                            this.slider_changing_programmatically--;
                        } else {
                            SearchPage.filterParams.min_price = positionToPrice( this.minVal );
                            SearchPage.filterParams.max_price = positionToPrice( this.maxVal );
                            SearchPage.updateFilters();
                        }
                    }
                    
                },true);
                
                slider.subscribe('change',slider.updateUI,slider,true);
                slider.subscribe('slideEnd',slider.endUpdateUI,slider,true);
                
                YAHOO.priceSlider.slider = slider;
            }
        );
    } ,

    filterParams : {} ,

    updateFiltersLastNum : 1 ,
    
    updateFilters : function(){
        SearchPage.updateFiltersLastNum++;
        var mynum = SearchPage.updateFiltersLastNum;
        window.setTimeout( 
            function(){
                if ( mynum != SearchPage.updateFiltersLastNum )
                    return;
                var url = "/ajax/results_only/" + originalQuery + "?";
                for ( var key in SearchPage.filterParams ) {
                    url += key + "=" + encodeURIComponent( SearchPage.filterParams[ key ] ) + "&";
                }
                SearchPage.getNewDataFromURL( url );
            } , 200 );
    }
    
}



WAITER = new YAHOO.widget.Panel("wait",  
                { width:"400px",
                  fixedcenter:true, 
                  close:true, 
                  draggable:false, 
                  zindex:32000,
                  modal:false,
                  visible:false
                } 
        );

WAITER.setHeader(LOADING_MESSAGE);
WAITER.setBody('<img src="/static/images/rel_interstitial_loading.gif" />');

// Store previous slider positions
slider_min = 0;
slider_max = 0;

// Used for searches after price slider changes
search_xhr = null;

if ( yahooLibraries.length > 0 ){
    var loader = new YAHOO.util.YUILoader();

    loader.insert(
        {
            require: yahooLibraries , 
            base: '/static/js/yui/build/' ,
            
            onSuccess: function(loader) {
                // Put a LogReader on your page
                if ( debugging ){
                    this.myLogReader = new YAHOO.widget.LogReader();
                }
            }
        }
    );
}

debug = function( msg , type ){
    if ( debugging )
        YAHOO[type||"log"]( msg );
}

function lift_search_results( elem ) {
  if ( elem == null ) return;
  children = YAHOO.util.Dom.getChildren(elem);
  elem.innerHTML = "";

  for ( var i = 0; i < children.length; ++i ) {
    elem = children[i];
    targ = document.getElementById( elem.id );
    if ( targ != null ) {
      targ.innerHTML = elem.innerHTML;
    }
  }
}

// Enable / disable checkboxes in the Brand Filter
function enable_filter_controls(enable) {
  var filter_controls = YAHOO.util.Dom.getElementsByClassName('filter_control');
  for (i = 0; i < filter_controls.length; i++) {
    var elem = filter_controls[i];
    if (elem.tagName == 'A') {
        // It's a link, so disable it by removing the href and disabling its
        // click handler
        elem.href = enable ? '#' : '';
        if (enable) {
            if ( elem.old_onclick ) {
                elem.onclick = elem.old_onclick;
            }
        } else {
            elem.old_onclick = elem.onclick;
            elem.onclick = function() { return false; }
        }
        
    } else {
        // It's a checkbox
        elem.disabled = ! enable;
    }
  }
}

// Called from the Brand Filter on the side of a search page -- when a checkbox
// next to, say, "Apple Computer" in the Brand Filter is checked, the search
// page updates to show only Apple products.  When unchecked, the page returns
// to normal.  Several brands can be checked at a time.
function filter_check(element_id, box_or_link) {
    the_box = document.getElementById(element_id);
    if (box_or_link == 'link') {
        // The link next to the box was clicked, so this function must check the
        // box; otherwise, the user checked the box directly
        the_box.checked = ! the_box.checked;
    }
    
    // Make brand boxes unclickable while we're updating the search page
    enable_filter_controls(false);
    
    // If user closes WAITER panel before the new, filtered search completes,
    // undo the user's action (checking or unchecking the box)
    onYUIPanelClose(
        WAITER,
        function() {
            if (the_box)
                the_box.checked = ! the_box.checked;
        },
        true // purge previous handlers
    );
    
    SearchPage.add_filter();
    
    // If user clicked box, return true to allow normal event execution; if
    // user clicked link, we overrode its behavior by checked the adjacent box,
    // so cancel event execution.
    return box_or_link == 'box';
}

/** Toggles an element's "display" style property between "block" and "none".
 * @param {Object|string} e Element or element id.
 */
function toggleElement ( e ) {
    var e = getElement( e );
    if ( e.style.display == "none" ) {
      e.style.display = "block";
    } else {
      e.style.display = "none";
    }
    
    return false;
}

function format_price(price, thousands_separator) {
    price = String(price);
    dot_index = price.indexOf('.');
    if(dot_index > 0) {
        fraction = price.substr(dot_index+1);
        whole = price.substr(0, dot_index);
    } else {
        whole = price;    
        fraction = '';
    }
    
    // If locale's thousands-separator is comma, decimal separator is dot, and vice versa
    decimal_separator = (thousands_separator == ',' ? '.' : ',');
    
    return PRICE_FORMAT_FUNCTIONS[PRICE_FORMAT](whole + decimal_separator + fraction);
}

var PRICE_FORMAT_FUNCTIONS = {
    add_dollar : function(price) { return '$' + price; },
    add_euro_before : function(price) { return '&euro; ' + price; },
    add_euro_after : function(price) { return price + ' &euro;' },
    add_pound : function(price) { return '&pound;' + price }
};

/* Detail page selector stuff */


function setClass(elem, str) {
    elem.className = str;
}


function largeSmallPopular( id , numelements ) {

  var cell = document.getElementById( "tab" + id );

    // small elements
    for(i = 1 ; i <= numelements ; i++ ) {
      if (i != id) {
            var temp = "tab" + i;
            var f = document.getElementById(temp);
            if (!f)
                continue;
            f.style.display = "none";
            var elem = document.getElementById( "control" + i );
            if (elem) {
                setClass( elem , "tab_notselected" );
            }
      }
    }

    // large element
    cell.style.display = "block";
    setClass( document.getElementById( "control" + id ) , "tab_selected" );

}

function truncate_descriptions(size) {
      $(".description_text").each(function (i) {
        t = $(this).text();
        if (t.length < size) {
            return true;
        }
        sub_t = t.substr(0, size);
        last_space = sub_t.lastIndexOf(' ');
        if ( last_space > 0 ) {
            // alert(last_space);
            sub_t = t.substr(0, last_space);
        }
        $(this).text(sub_t + '...');
        return true;
      });
}

function x_url(id, title, prefix, p){
    var url = prefix + title;
    var container = document.getElementById(id + '_cont');
    var contents = document.getElementById(id);
    var anchor = document.createElement("A");
    
    if ( p.length > 0 ) {
        url += url.indexOf('?') > 0 ? '&' : '?'
    }

    for(var i = 0; i < p.length; i++) {
        if ( i % 2 == 0) { 
            url += p[i];
        } else {
            url += '=' + p[i] + '&'
        }
    }
    
    // this seems too slow on slow computers, and it affects how the page looks
    // $(document.getElementById('id')).ready(function() {
    //     $('#' + id + '_cont').append(
    //         $('<A href="'+url+'"></A>').append($('#' + id))
    //     );
    // })


    anchor.href = url;

    anchor.innerHTML = contents.innerHTML;
    contents.innerHTML = '';

    // for(var i = 0; i < contents.childNodes.length; i++) {
    //     var x = contents.childNodes[i];
    //     anchor.appendChild(x);
    // }
    container.appendChild(anchor);
    var temp = container;
}

function durl(id, title, p) {
    x_url(id, title, '/_', p);
}

function lurl(id, title, p) {
    x_url(id, title, '/', p)
}

function add_page(page) {
    var url = $('#link_to_this_page_new').text();  //window.location.href.replace('#','');
    // alert(url);
    var param = 'page=' + page;
    var has_query = url.indexOf('?') > 0;
    if (has_query) {
        if(url.indexOf('page=') > 0) {
            url = url.replace(/page=\d+/g, param)
        } else {
            url += '&' + param
        }
    } else {
        url = url + '?' + param
    }
    
    return url
}

function page_link(num, klass, linktext) {
    var span = document.createElement("SPAN");
    span.className = klass
    
    var a = document.createElement("A");
    a.innerHTML = linktext;
    a.href = add_page(num)
    
    span.appendChild(a);
    return span;
}

function paginate(pages, show_prev, prev, show_next, next, page, prev_trans, next_trans) {
    var cont = document.getElementById('pagination');
    if(show_prev) {
        cont.appendChild(page_link(prev, 'page_number previous_page', prev_trans));
    }
    
    for( var i = 0; i < pages.length; i++) {
        if(pages[i] == page) {
            var ospan = document.createElement("SPAN");
            ospan.className = "page_number";
            
            ispan = document.createElement("SPAN");
            ispan.className = "current_page";
            ispan.innerHTML = pages[i];
            
            ospan.appendChild(ispan);
            cont.appendChild(ospan);
        } else {
            cont.appendChild(page_link(pages[i], 'page_number', pages[i]));
        }
    }
    if(show_next) {
        cont.appendChild(page_link(next, 'page_number next_page', next_trans));
    }
}

// Stuff I had to port from the old UI, that I'd like to get rid of
function replaceAll( str , from, to ){
    while ( true ){
        var next = str.replace( from , to );
        if ( next == str )
            return next;
        str = next;
    }
    return str;
}

function stripHTML( s ){
        return replaceAll( s , /<[^>]*>/ , "" );
}

function getStoreLink( url , noLink , toIgnore ){
    url = trim(url);
    url = replaceAll( url , " " , "+" );

    var storeURL = url;
    if ( url.indexOf( "stat.dealtime" ) >= 0 ){
        var tempIdx = storeURL.indexOf( "url=" );
        if ( tempIdx > 0 )
            storeURL = storeURL.substring( tempIdx+ 17 );
        tempIdx = storeURL.indexOf( "%" );
        if ( tempIdx > 0 )
            storeURL = storeURL.substring( 0 , tempIdx );

        storeURL = storeURL.replace( "rdr.channelintelligence.com" , ".com" );
    }
    else {
        storeURL = storeURL.substring( storeURL.indexOf("//") + 2 );
        var tempIdx = storeURL.indexOf("/");
        if ( tempIdx > 0 ){
            storeURL = storeURL.substring( 0 , tempIdx );

            if ( storeURL == "store.yahoo.com" ){
                storeURL = url;
                storeURL = storeURL.substring( storeURL.indexOf("//") + 2 );
                storeURL = storeURL.substring( storeURL.indexOf("/") + 1 );

                tempIdx = storeURL.indexOf("/");
                if ( tempIdx > 0 ){
                    storeURL = storeURL.substring( 0 , tempIdx );
                }

                storeURL = "yahoo/" + storeURL;
            }

        }

        tempIdx = storeURL.indexOf("?");
        if ( tempIdx > 0 ){
            storeURL = storeURL.substring( 0 , tempIdx );
        }
    }

    while ( 1 ){
        tempIdx = storeURL.indexOf(".");
        if ( tempIdx < 0 )
            break;
        var pc = storeURL.substring(0,tempIdx);
        if ( pc != "store" && pc != "www" && pc != "cgi" )
            break;
        storeURL = storeURL.substring( tempIdx + 1 );
    }

    if ( toIgnore ){
        if ( toIgnore[storeURL] == "t" ){
            return "";
        }
        toIgnore[storeURL] = "t";
    }

    storeURL = trim(storeURL.toLowerCase());
    storeURL = storeURL.replace( "\.\.", "." );
    if ( storeURL.length == 0 || storeURL.charAt(0) == ' ' ){
        return null;
    }

    if ( noLink ){
        return storeURL;
    }
    return "<a target='new_"+Math.random()+"' class='green' href='" + url + "'>" + storeURL +  "</a>" ;

}

function trim(str){
    return str.replace(/^\s*|\s*$/g,"");
}


function cleanNonJSHappy( s ){
    s = replaceAll( s , /['"]/ , "" );
    return s;
}

/** Do something when a YUI panel is closed by the user
  @param panel {YUI.widget.Panel}  A panel.
  @param handler {function}  Do this when the panel closes.
  @param do_purge {bool}  If true purge previous close-handlers.
*/
function onYUIPanelClose( panel, handler, do_purge ) {
    if (do_purge) {
        // Remove past click-handlers added to the panel's close button
        YAHOO.util.Event.purgeElement(
            // panel.close is the x-button element
            panel.close,
            false, // no recurse
            'click'
        );
    }
    
    YAHOO.util.Event.on(
        panel.close,
        'click',
        function() { handler(); this.hide(); },
        panel,
        true
    );
}
