var search_results;
function updateOfferNotes() {
  if ($(this).val() == '1') {
    // 'accept' is selected
    $('#id_reject_notes').html($('#id_notes').val());
    $('#id_notes').val($('#id_accept_notes').html());
  } else {
    // 'reject' is selected.
    // remember what was in textarea
    $('#id_accept_notes').html($('#id_notes').val());
    $('#id_notes').val($('#id_reject_notes').html());
  }
}
function insertListEvents() {
// handles inserting the returned json data to the relevant element
  var result = "";
  var result_count = 0;
  var data = search_results;
  if (data == undefined) return;
  if (data['status'] == 'ok') {
    $.each(data.events, function(i,item){
      //result += "<li>" + item['title'] + "</li>";
      if (item['li'] != undefined) {
        result += item['li'];
      } else {
        result += "<li>" + item['title'] + "</li>";
      }
      result_count++;
    });
    if (result_count > 0) {
      $('#list_main').append(result);
    }
    $('#output').empty().append('Found ' + result_count + ' results');
    // install ajax handlers for 'edit' links
    $('#list_main').ready(function() {
      $('.edit').bind('click', function() {
        //alert('hi');
        // do the ajax call and load returned form in a modal panel...
        // form comes over pre-populated
        //alert(this + '?xhr');
        $.getJSON(this + '?xhr', function(data) {
          if (data['status'] == 'ok') {
            //alert('getJSON returned: ' + data['status']);
            // insert the form into a table within the #dialog element
            $('#dialog_title').empty().append("Edit '" + data['title'] + "'");
            $('#form_table').empty().append(data['form']);
            //$('#dialog').dialog({'modal': true});
            $('#form_table').ready(function() {
              $('#dialog').dialog({'modal': true, 'draggable': false, 'height': 'auto', 'width': 'auto'});
            });
          } else {
            alert('getJSON returned: ' + data['status']);
          }
        });
        return false;
      });
    });
  } else {
    // data['status'] != 'ok' ...
    $('#output').empty().append(data['message']);
  }
}
function insertGalleryEvents() {
// handles inserting the returned json data to the relevant element
  var result = "";
  var result_count = 0;
  var data = search_results;
  if (data == undefined) return;
  if (data['status'] == 'ok') {
    $.each(data.events, function(i,item){
      if (item['div'] != undefined) {
        result += item['div'];
      } else {
        result += "<div>" + item['title'] + "</div>";
      }
      result_count++;
    });
    if (result_count > 0) {
      $('#gallery_view').append(result);
    }
    $('#output').empty().append('Found ' + result_count + ' results');
  } else {
    // data['status'] != 'ok' ...
    $('#output').empty().append(data['message']);
  }
}
function storeEvents(data) {
  search_results = data;
  // insert into whichever view is visible currently
  //alert('hi' + $('input:radio[@name=view_type]').val());
  // if ('list' == $('input:radio[@name=view_type]').val()) {
  // alert($('input:radio[@name=view_type]:checked').val());
  $('#list_main').empty();
  $('#gallery_view').empty();
  eventSource.clear();
  if ('list' == $('input:radio[@name=view_type]:checked').val()) {
    //alert('list');
    insertListEvents();
  } else if ('gallery' == $('input:radio[@name=view_type]:checked').val()) {
    // alert('gallery');
    insertGalleryEvents();
  } else if ('timeline' == $('input:radio[@name=view_type]:checked').val()) {
    // alert('timeline');
    eventSource.loadJSON(search_results, '');
  }
}
function getEvents(url) {
  $('#list_main').empty();
  $('#output').empty().append('Searching...');
  $.getJSON(url, storeEvents);
}
/*function showPageControls(html) {
  $('#page_controls_id').empty().append(html);
}*/
var tl;
var eventSource;
var bandInfos;
function createTimeline() {
  // set up timeline
  //var theme = Timeline.ClassicTheme.create(); // create the theme
  //theme.timeline_start = earliest_date;
  //theme.timeline_stop = latest_date;
  //   theme.event.bubble.width = 350;   // modify it
  //   theme.event.bubble.height = 300;
  //   theme.event.track.height = 15;
  //   theme.event.tape.height = 12;
  //var d = Timeline.DateTime.parseGregorianDateTime(earliest_date.toUTCString());
  bandInfos = [
    Timeline.createBandInfo({
      layout: 'overview',
      eventSource:    eventSource,
      //eventPainter:   Timeline.OverviewEventPainter,
      //showEventText:  false,
      //trackHeight:    1.0,
      //trackGap:       0.2,
      width:          "10%", 
      //theme: theme,
      intervalUnit:   Timeline.DateTime.YEAR, 
      //date:           d,
      intervalPixels: 100
    }),
    Timeline.createBandInfo({
      width: "90%", 
      //eventSource:    eventSource,
      layout: 'original',
      intervalUnit: Timeline.DateTime.MONTH, 
      //date:           d,
      //date: earliest_date,
      //theme: theme,
      eventSource: eventSource,
      intervalPixels: 50
    })
  ];
  bandInfos[0].syncWith = 1;
  bandInfos[0].highlight = true;
  // bandInfos[1].showEventText = false;
  // bandInfos[2].syncWith = 1;
  // bandInfos[2].highlight = true;
  tl = Timeline.create(document.getElementById("timeline"), bandInfos);
  /*Timeline.OriginalEventPainter.prototype._showBubble = function(x, y, evt) {
    alert('hi');
  };*/
}
function insertCommentForm(insert_el, action_url) {
  /* ref. templates/questions/popup/answer.html */
  // move comment form into dom
  // FIXME:
  $('#question_comment').appendTo(insert_el);
  //this.before($('#question_comment'));
  // make visible
  $('#question_comment').show();
  $('#id_comment').focus();
  // bind 'submit' to the url specified in params
  $('#question_comment_form').bind('submit', function(){
    // hide the form on submission, so it can't be sent twice
    $('#question_comment').hide();
    $(this).ajaxSubmit({
      type: 'POST',
      url: action_url,
      success: function(data) {
        // FIXME:
        // update the container with the new content...
        $('#output').empty();
        //$('#dialog').dialog('open').empty().append(data);
      },
      error: function(data, status, e) {
        $('#output').empty().append('xhr error: ' + status);
      }
    });
    return false;
  });
}
function postForm() {
  //console.log('postForm()');
  $(this).find('.message').empty().append('Saving <img src="/site_media/images/progress-running.gif">');
  $(this).ajaxSubmit({
    type: 'POST',
    url: $(this).attr('action'),
    success: function(data) {
      $('#output').empty();
      $('#dialog').dialog('open').empty().append(data);
      //$('#dialog').empty().append(data);
      //$('#dialog').dialog('option', 'title', 'problem?');
      $('#dialog').find('.popup_link').bind('click', popupLink);
      $('#dialog').find('.popup_form').each(
        function() {  // hijack form submission to use ajax...
          $(this).bind('submit', postForm);
        });
      var title = $('#dialog #form_title').html();
      $('#dialog #form_title').remove(); // since we display the element as the dialog title
      $('#dialog').dialog('title', title);
      $('#accordion').accordion();
      //$('#dialog select').selectbox();
    },
    error: function(data, status, e) {
      $('#output').empty().append('xhr error: ' + status);
      $('.message').empty().append('Error: ' + status);
    }
  });
  return false;
}
function getSettings() {
  var url = $(this).attr('href');
  var anchor = $(this);
  $.get(url, function(data) {
    var el = $(anchor).parents('.settings_div');
    // empty the dialog element, and append the html fragment that 
    // was returned by the ajax request
    $(el).empty().append(data);
    // when the dom element is ready
    $(el).ready(function() {
      // add ajax handler for form submission from profiles/settings.html
      // where we swap the returned content into a div inside the dialog
      $('.settings_form').each(function() {
        $(this).bind('submit', postSettings);
      });
      // add ajax handler for link that refreshes section content in settings.
      $('.settings_link').each(function() {
        $(this).bind('click', getSettings);
      });
      //$('#dialog select').selectbox();
    });
  });
  return false;
}

function postSettings() {
  var form = $(this);
  $(this).find('.message').empty().append('Saving <img src="/site_media/images/progress-running.gif">');
  $(this).ajaxSubmit({
    type: 'POST',
    url: $(this).attr('action'),
    success: function(data) {
      $('#output').empty();
      // insert the returned data at the parent .settings_div
      var el = form.parents('.settings_div');
      //el.each(function() { this.empty().append(data); });
      el.empty().append(data);
      //alert(insert_to.attr('id'));
      //insert_to.empty().append(data);
      el.ready(function() {
        $(this).find('.settings_form').each(
          function() {  // hijack form submission to use ajax...
            $(this).bind('submit', postSettings);
          });
        // add ajax handler for link that refreshes section content in settings.
        $(this).find('.settings_link').each(
          function() {
            $(this).bind('click', getSettings);
        });
        //$('#dialog select').selectbox();
        Dialog.refresh = true;
      });
    },
    error: function(data, status, e) {
      $('#output').empty().append('xhr error: ' + status);
    }
  });
  return false;
}
var current_hash = '';
function updateState(hash, el) {
  //console.log('updateState()');
  // load the content via an ajax request from the url in the hash
  if ((hash != current_hash) && (hash != "") && (hash != "#")) {
    current_hash = hash;
    // popup a jquery dialog...
    $(el).dialog('open').empty().append("<img src='/site_media/images/progress-running.gif'/>");
    
    // init the load of content based on the hash value
    $.ajax({
      url: hash, //hash.substring(1),
      type: 'GET',
      //dataType: 'json',
      //contentType: 'application/json; charset=utf-8',
      success: function(data) {
        // empty the dialog element, and append the html fragment that 
        // was returned by the ajax request
        $(el).empty().append(data);
        // when the dom element is ready
        $(el).ready(function() {

          // Hacker McHack:
          $('#id_accept_1').bind('change', updateOfferNotes);
          $('#id_accept_0').bind('change', updateOfferNotes);
          // set initially to 'accept' notes...
          $('#id_notes').val($('#id_accept_notes').html());
          
          // add popup handler for any popup links in the dialog
          $(this).find('.popup_link').each(
          function() {
            $(this).bind('click', popupLink);
          });
          // override the 'click' for transient dialogs
          $(this).find('.transient').each(
          function() {
            $(this).bind('click', transientLink);
          });
          // and ajax handler for form submission, so we don't do a full page refresh
          $(this).find('.popup_form').each(
            function() {  // hijack form submission to use ajax...
              //console.log('binding for: ' + $(this).attr('id'));
              $(this).bind('submit', postForm);
          });
          // add ajax handler for form submission from profiles/settings.html
          // where we swap the returned content into a div inside the dialog
          $(this).find('.settings_form').each(
            function() {
              $(this).bind('submit', postSettings);
          });
          // add ajax handler for link that refreshes section content in settings.
          $(this).find('.settings_link').each(
            function() {
              $(this).bind('click', getSettings);
          });
        });
        // FIXME:
        // grab the title from an h1 element in the returned data if there is
        var title = $('#form_title').html();
        $('#form_title').remove(); // since we display the element as the dialog title
        $(el).dialog('close');
        $(el).dialog('option', 'title', title);
        if ($('#dialog').length > 0) {
         var width = parseInt($('#dialog').css('width'), 10) + 20;
         //$(el).dialog('option', 'width', width);
         $(el).data("width.dialog", 750);
        }
        $(el).dialog('open');
        $('#dialog input:first').focus();
        // create accordion for profile/settings/
        $("#accordion").accordion();
        $('#dialog').dialog('option', 'position', 'center');
        //$('#dialog select').selectbox();
      },
      error: function(data, status, e) {
        $('#output').empty().append('xhr error: ' + status);
      }
    });
  } else {
    $(el).dialog('close');
  }
}
function transientLink() {
  $('#transient').empty();
  var href = '';
  href = $(this).attr('href');
  updateState(href, '#transient');
  return false;
}
function popupLink() {
  // $(this) should be a <a> element which we want to hijack
  // clear the dialog, assuming the popup is going to load new content
  $('#dialog').empty();
  var href = '';
  href = $(this).attr('href');
  //if ($(this).attr('href')[0] != "#") {
  //  $(this).attr('href', '#'+href);
  //}
  updateState(href, '#dialog');
  return false;
}
function popupDialog(url) {
  $('#dialog').empty();
  updateState(url, '#dialog');
  return false;
}
// refer items/url.py 'item_detail_order'
function insertDetailPhotos(data, textStatus) {
  // html fragment for #detail_photos_order
  $('#detail_photos_order').html(data).ready(function() {
    installDetailPhotosHandler();
    var img_src = $('#detail_main_photo').attr('src');
    // install new main_photo in each section of item display popup
    $('#dialog').find('img.main_photo').attr('src', img_src);
    // cancel the 'saving' + spinner next to button
    $('.message').empty();
    Dialog.refresh = true; // force page refresh on dialog close.
  });
}
function installDetailPhotosHandler() {
  // update main_photo_id with first src url from first detail photo
  var image_url = $('#imagelist_id:first').find('img').attr('src');
  if (image_url) {
    image_url = image_url.replace("manage", "thumbnail");
    $("#main_photo_id").attr("src", image_url);
  }
  // make detail photo list sortable
  $("#imagelist_id").sortable({
    axis: 'y',
    stop: function(event, ui) {
      $('.message').empty();
    },
    start: function(event, ui) {
      $('.message').empty().append('Sorting <img src="/site_media/images/progress-running.gif"/>');
    },
    update: function(event, ui) {
      var val = $('#imagelist_id').sortable('serialize');
      // display a progress indicator...
      $('#detail_progress').show();
      $('.message').empty().append('Saving <img src="/site_media/images/progress-running.gif"/>');
      // get the url for item_detail_order from a form
      var url = $('#detail_order_form').attr('action');
      $.get(url + '?' + val, {}, insertDetailPhotos);
      $('#detail_progress').hide();
    }
  }).disableSelection();
  return 'ok';
}
function swapForMainPhoto(image_url) {
  $("#main_photo_id").attr("src", image_url);
}
function closeDialog() {
  $('#dialog').dialog('close');
  current_hash = '';
}
function scrollToYear(year) {
  tl.getBand(0).scrollToCenter(Timeline.DateTime.parseGregorianDateTime(year));
}
var Dialog = function() {
  return {
    refresh: false,
    close: function() {
      $('#dialog').dialog('close');
      current_hash = '';
    },
    attachHandlers: function() {
      $('.settings_form').each(
        function() {
          $(this).bind('submit', postSettings);
      });
      // add ajax handler for link that refreshes section content in settings.
      $('.settings_link').each(
        function() {
          $(this).bind('click', getSettings);
      });
    }
  };
}();
var Comments = function() {
  // private vars
  
  // private functions
  
  return {
    // public methods
    load: function(selector, url) {
      $('.message').empty().append('<img src="/site_media/images/progress-running.gif"/>');
      $.ajax({
        url:url,
        type:'GET',
        success:function(data) {
          $(selector).empty().append(data);
          Comments.attachHandlers();
        },
        error:function(data) {}
      });
    },
    // install handlers for comment forms
    attachHandlers: function() {
      $('.remove_comment_form').bind('submit', function() {
        var self = $(this);
        $(this).ajaxSubmit({
          success: function(data) {
            var comment_id = self.find('#comment_id').attr('value');
            $('#comments_container').empty().append(data);
            Comments.attachHandlers();
          },
          error: function(data) {
            var comment_id = self.find('#comment_id');
            $('#comments_container' + comment_id).empty().append(data);
          }
        });
        return false;
      });
      $('.attach_comment').bind('click', function() {
        $('#item_comment_form').unbind('submit');
        var action_url = $(this).attr('rel'); // url to post comment to. use as form action.
        var insert_el = $(this).attr('href');
        // attach comment form to 
        $('#item_comment').appendTo(insert_el);
        //this.before($('#question_comment'));
        // make visible
        $('#id_comment').attr('value', '');
        $('#item_comment').show();
        $('#id_comment').focus();
        // bind 'submit' to the url specified in params
        $('#item_comment_form').bind('submit', function(){
          // hide the form on submission, so it can't be sent twice
          $('#item_comment').parent().append('Posting comment. <img src="/site_media/images/progress-running.gif"/>');
          $('#item_comment').hide();
          $('#item_comment_form').ajaxSubmit({
            type: 'POST',
            url: action_url,
            success: function(data) {
              // update the container with the new content...
              $('#output').empty();
              $('#comments_container').empty().append(data);
              Comments.attachHandlers();
            },
            error: function(data, status, e) {
              $('#output').empty().append('xhr error: ' + status);
            }
          });
          return false;
        });
        return false;
      });
    }
  };
}();
var CCSearch = function() {
  // the code here is tightly coupled with the html template fragment in
  // templates/search.html including the <script> fragment there.
  var object = {
    'item': 'items',
    'collection': 'collections',
    'listing': 'trades',
    'favorite': 'favorites',
    'friend': 'friends',
    'message': 'messages',
    'comment': 'comments',
    'member': 'members',
    'club': 'clubs',
    'question': 'Q&A'
  };
  var from = {
    //'here': 'here: ',
    'member': 'My Home',
    'all': 'Community',
    'natural': 'Natural History',
    'popular': 'Popular Culture',
    'historical': 'Historical & Antique',
    'wearables': 'Wearables',
    'art': 'Art & Craft',
    'mechanical': 'Mechanical & Scientific',
    'curiosa': 'Curiosa & Misc'
  };
  var by = {
    'any': 'any',
    'keyword': 'keyword',
    'year': 'year'
  };
  var price = {
    'swap': 'to swap',
    'free': 'to give away',
    'any': 'all for sale',
    'under10': 'under $10',
    'under50': 'under $50',
    'under100': 'under $100',
    'under500': 'under $500',
    'under1000': 'under $1000',
    'over1000': 'over $1000'
  };
  var question = {
    'unanswered': 'unanswered',
    'answered': 'answered',
    'asked_by_friends': 'asked by friends',
    'asked_by_me': 'asked by me',
    'answered_by_me': 'answered by me'
  };
  var sort = {
    'ascending': 'ascending',
    'descending': 'descending',
    'recent': 'recent',
    'earliest': 'earliest',
    'largest': 'largest',
    'views': 'view count'
  };
  // patterns for urls of each section
  // the path components starting with '_' are swapped out for the
  // selected option in the corresponding <select> element.
  var generic_url = '_sphere/_search_by/_sort_by/';
  //
  var urlpatterns = {
    'member': {
      'item': '/member/items/' + generic_url,
      'collection': '/member/collections/_search_by/_sort_by/', // no sphere within member collection search
      'listing': '/market/',
      'favorite': '/member/favorites/' + generic_url,
      'friend': '/member/friends/_sort_by/',
      'message': '/messages/inbox/',
      'comment': '/member/comments/',
      'member': '/community/members/' + generic_url,
      'club': '/member/clubs/all/_search_by/_sort_by/',
      'question': '/questions/_search_question/_sphere/_search_by/'
    },
    'community': {
      'item': '/community/items/' + generic_url,
      'collection': '/community/collections/_search_by/_sort_by/',
      'listing': '/market/',
      'favorite': '/community/favorites/' + generic_url,
      'friend': '/member/friends/_sort_by/',
      'message': '/messages/inbox/',
      'comment': '/community/comments/',
      'member': '/community/members/' + generic_url,
      'club': '/community/clubs/' + generic_url,
      'question': '/questions/_search_question/_sphere/_search_by/'
    },
    'club': {
      'comment': '/community/club/_tribe_slug/discussions/',
      'item': '/community/club/_tribe_slug/items/',
      'member': '/community/club/_tribe_slug/members/',
      'club': '/community/club/_tribe_slug/'
    },
    'market': {
      'item': '/market/_search_price/_sphere/_sort_by/'
      // 'swap': '',
      // 'free': '',
      // 'any': '',
      // 'under10': '',
      // 'under50': '',
      // 'under100': '',
      // 'under500': '',
      // 'under1000': '',
      // 'over1000': ''
    }
  };
  // nav_visibility isn't used, but is intended to express which
  // select elements remain valid input for which object type.
  var nav_visibility = {
    'member': {
      'item': ['from', 'by', 'sort'],
      'collection': ['by', 'sort']
    },
    'community': {},
    'market': {}
  };
  var this_keyword = '';
  var get_search_url = function() {
    // generate a url from the current state of the search input
    // var 'nav_section' is set in the base.html template.
    var url = '/' + section + '/';
    var object_type = $('#search_object').val();
    if (object_type == '') object_type = 'item';
    var search_by = $('#search_by').val();
    if (search_by == '') search_by = 'any';
    var sort_by = $('#search_sort').val();
    if (sort_by == '') sort_by = 'recent';
    var from = $('#search_from').val();
    if (from == '') from = 'here';
    var keyword = $('#search_keyword').val();
    var start_year = $('#search_year_start').val();
    var end_year = $('#search_year_end').val();
    var price = $('#search_price').val();
    if (price == '') price = 'any';
    
    var search_section = 'community';
    if (from == 'member') {
      search_section = 'member';
      from = 'all';
    } else if (from == 'community') {
      from = 'all';
    } else if (section == 'market') {
      search_section = 'market';
    } else if (from == 'club') {
      search_section = 'club';
    }
    
    if (search_by == 'keyword' && typeof(keyword) != 'undefined' && keyword != '') {
       search_by = 'keyword/' + keyword;
    } else if (search_by == 'year') {
      search_by = 'year/' + start_year + '-' + end_year;
    } else {
      search_by = 'any';
    }
    
    if (here_search_question == '') {
      here_search_question = 'answered';
    }
    
    // get section
    //url = urlpatterns[search_section];
    url = urlpatterns[search_section][object_type];
    // perform substitutions of input state into URL pattern
    url = url.replace(/_sphere/, from);
    url = url.replace(/_search_by/, search_by);
    url = url.replace(/_sort_by/, sort_by);
    url = url.replace(/_search_question/, here_search_question);
    url = url.replace(/_search_price/, price);
    if (typeof(tribe_slug) != 'undefined') url = url.replace(/_tribe_slug/, tribe_slug);

    return url;
  };
  return {
    get_url: function() {
      return get_search_url();
    },
    submit: function() {
      window.location = CCSearch.get_url();
      return false;
    },
    init: function() {
      if (typeof(here_is) == 'undefined') return;
      // bind 'change' on all select inputs in form.
      $('#search_form select').bind('change', CCSearch.update_visibility);
      $('#search_sort').bind('change', CCSearch.update_visibility);
      //
      var keyword_input = $('#search_keyword');
      if (keyword_input.length > 0) {
        keyword_input.bind('change', function() {
          if ($(this).val().length > 0) {
            $('#search_by').val('keyword');
          }
        });
      }
      //
      $('#search_year_end').bind('change', CCSearch.update_visibility);
      $('#search_year_start').bind('change', CCSearch.update_visibility);

      // 'SEE' dropdown for member/community sections
      var object_select = $('#search_object');
      if (object_select.length > 0) {
        var dropdownList = object_select[0];
        var o = document.createElement('option');
        o.text = 'FIND';
        o.value = '';
        dropdownList.add(o, null);
        for (var i in object) {
          //var option = new Option(object[i], i);
          var o = document.createElement('option');
          o.text = object[i];
          o.value = i;
          dropdownList.add(o, null);
        }
      }
      // listing 'SEE' dropdown for marketplace section
      var price_select = $('#search_price');
      if (price_select.length > 0) {
        var dropdownList = price_select[0];
        dropdownList.add(new Option('SEE', ''), null);
        for (var i in price) {
          var option = new Option(price[i], i);
          dropdownList.add(option, null);
        }
      }
      // question 'SEE' dropdown for questions section
      var question_select = $('#search_question');
      if (question_select.length > 0) {
        var dropdownList = question_select[0];
        dropdownList.add(new Option('SEE', ''), null);
        for (var i in question) {
          var option = new Option(question[i], i);
          dropdownList.add(option,  null);
        }
      }
      // populate the 'FROM' select element
      var from_select = $('#search_from');
      if (from_select.length > 0) {
        var dropdownList = from_select[0];
        dropdownList.add(new Option('FROM', ''), null);
        if (here_is.length > 15) {
          here_is = here_is.substring(0, 15) + '...';
        }
        if (section == 'community' && typeof(tribe_slug) != 'undefined') {
          dropdownList.add(new Option('Here: ' + here_is, 'club'), null);
        } else {
          dropdownList.add(new Option('Here: ' + here_is, section), null);
        }
        for (var i in from) {
          var option = new Option(from[i], i);
          dropdownList.add(option, null);
        }
      }
      // populate the 'BY' select element
      var by_select = $('#search_by');
      by_select.bind('change', function() {
        // focus the year_start input
        $('#search_year_start').focus();
      });
      if (by_select.length > 0) {
        var dropdownList = by_select[0];
        dropdownList.add(new Option('BY', ''), null);
        for (var i in by) {
          var option = new Option(by[i], i);
          dropdownList.add(option, null);
        }
      }
      // populate the 'VIEW BY' select element
      var sort_select = $('#search_sort');
      if (sort_select.length > 0) {
        var dropdownList = sort_select[0];
        dropdownList.add(new Option('VIEW BY', ''), null);
        for (var i in sort) {
          var option = new Option(sort[i], i);
          dropdownList.add(option, null);
        }
      }
      // set initial options of select inputs to reflect current URL if appropriate
      $('#search_question').val(here_search_question);
      $('#search_keyword').val(here_search_keyword);
      $('#search_by').val(here_search_by);
      $('#search_object').val(here_object_type);
      $('#search_from').val(here_search_from);
      $('#search_sort').val(here_sort_by);
      $('#search_price').val(here_search_price);
      
      if (here_search_from != 'member' && here_sphere != '') {
        $('#search_from').val(here_sphere);
      }
      if (section == 'messages') {
        $('#search_object').val('message');
      }
      // hijack 'search' button
      $('#search_form').bind('submit', function() {
        return CCSearch.submit();
      });
      $('#search_form').show();
      this.update_visibility();
      return false;
    },
    update_visibility: function() {
      // var 'nav_section' is set in base.html
      // store the keyword value if we're switching away from 'keyword'
      var keyword = $('#search_keyword').val();
      var search_by = $('#search_by').val();
      if (search_by != 'keyword' && keyword != '') {
        this_keyword = keyword;
        $('#search_keyword').val('');
      } else if (search_by == 'keyword' && this_keyword != '') {
        $('#search_keyword').val(this_keyword);
      }
      switch(section) {
        case 'messages':
        case 'questions':
          //$('#search_listing').hide();
          //$('#search_from').hide();
          //$('#search_by').hide();
          //break;
        case 'member':
        case 'community':
          // hide marketplace inputs
          $('#search_price').hide();
          $('#search_from').show();
          $('#search_by').show();
          break;
        case 'market':
          // hide 'object_type'
          $('#search_price').show();
          $('#search_object').val('item');
          $('#search_object').hide();
          break;
      }
      
      var object_select = $('#search_object');
      var object_type = object_select.val();
      switch (object_type) {
        case 'question':
          if (search_by == 'year') {
            $('#search_by').val('any');
          }
        //   $('#search_question').show();
        //   break;
        default:
          $('#search_question').hide();
          break;
      }
      // hide controls related to 'BY' select
      var by_select = $('#search_by');
      var by_type = by_select.val();
      if (by_type == 'year') {
        $('.year_group').show();
      } else {
        $('.year_group').hide();
      }
      $('#url_preview').html(get_search_url());
    }
  };
}();
$(document).ready(function() {
  CCSearch.init();
  $('.accordion').show();
  $('.accordion').accordion();
  //installDetailPhotosHandler(); // handler for item detail photos
  $('select.custom').selectbox();
  //$('select').selectmenu({style:'dropdown'});
  // show default view...
  // $('#timeline').show();
  // $('#gallery_view').hide();
  // $('#list_view').hide();
  // create a dialog for popups
  $('#dialog').dialog({
    autoOpen: false,
    draggable: false,
    // stack: false,
    stack: true,
    title: 'loading...',
    modal: true,
//    width: auto,
//    height: auto,
    // autoResize:true,
    // position:['center', 'top'],
    // show:'blind',
    // hide:'blind',
    resizable:false,
    close: function(event, ui) { 
      // remove hash fragment from url
      //current_hash = document.location.hash = "#";
      if (Dialog.refresh == true) {
        window.location.href = window.location.href;
        // firefox might not like window.location.href to refresh
        document.location.reload();
      }
      current_hash = '';
      return false;
    }
  });
  $('#transient').dialog({
    autoOpen: false,
    draggable: false,
    // stack: false,
    stack: true,
    title: 'loading...',
    modal: true,
//    width: auto,
//    height: auto,
    // autoResize:true,
    // position:['center', 'top'],
    // show:'blind',
    // hide:'blind',
    resizable:false
/*    close: function(event, ui) { 
      // remove hash fragment from url
      current_hash = document.location.hash = "#";
      return false;
  }*/
  });
  // hide icons until their row is rolled over
/*
  $('.icon').hide();
  $('.entry').bind('mouseover', function() {
    $(this).find('.icon').show();
  });
  $('.entry').bind('mouseout', function() {
    $(this).find('.icon').hide();
  });
*/
  // setup 'select all' link for items
  // see templates/items/items.html
  $('#items_select_all').bind('click', function() {
    // select all the checkboxes
    $('.item_checkbox').attr('checked', 'checked');
    return false;
  });
  $('#items_select_none').bind('click', function() {
    // deselect all the checkboxes
    $('.item_checkbox').attr('checked', '');
    return false;
  });

  // setup popup links for displaying individual items/clubs/members
  $('.popup_link').bind('click', popupLink);
/*  $('.popup_link').each(
    function() {
      var href = $(this).attr('href');
      if ($(this).attr('href')[0] != "#") {
        $(this).attr('href', '#'+href);
      }
    });
*/
  // action <select> in templates/sidebar/club.html
  $('#club_go').bind('click', function() {
    var url = $('#club_url_select').val();
    if (url) {
      $('#dialog').empty();
      updateState(url, '#dialog');
    }
    return false;
  });
  $('#object_create_id').bind('click', function() {
    // ajax load a form for adding the type of object...
    // clear dialog form (to avoid flash of previous dialog content)
    $('#dialog').empty();
    // then find the url corresponding to currently selection option
    var url = $('#new_object_type_id').val();
    if (url) {
      // let hashupdate handle the ajax loading of dialog content
      //location.hash = url;
      //updateState(url);
      $('#dialog').empty();
      // let hashupdate handle the popup
      //var href = $(this).attr('href');
      updateState(url, '#dialog');
    }
    return false;
  });

  // set up hashchange handler for fragment ajax navigation (loading popups)
  //$(window).hashchange(function() { updateState(location.hash, '#dialog'); });
  //updateState(location.hash, '#dialog');
  // set up radio buttons to create timeline when required
  //if (window.Timeline) {
  if(typeof(window.Timeline) != "undefined" && typeof(items) != "undefined" && $('#timeline').length != 0) {
    eventSource = new Timeline.DefaultEventSource();
    // get earliest/latest dates;
    var earliest_date = new Date();
    var latest_date = new Date();
    if (items.events.length) {
      earliest_date = new Date(items.events[0].start);
      latest_date = new Date(items.events[0].start);
      for (var i = 0; i < items.events.length; i++) {
        if (new Date(items.events[i].start) < earliest_date) {
          earliest_date = new Date(items.events[i].start);
        }
        if (new Date(items.events[i].end) && (new Date(items.events[i].end) > latest_date)) {
          latest_date = new Date(items.events[i].end);
        } else if (new Date(items.events[i].start) > latest_date) {
          latest_date = new Date(items.events[i].start);
        }
      }
    }
//    createTimeline();
    var theme = Timeline.ClassicTheme.create(); // create the theme
    theme.timeline_start = earliest_date;
    theme.timeline_stop = latest_date;
    theme.mouseWheel = 'default';
    //theme.iconHeight = 100;
    //theme.event.instant.iconWidth += 4; // Add padding and borders
    //theme.event.instant.iconHeight += 4;
    theme.event.instant.icon = "/site_media/images/collection_blank.gif";
    // get a suitable interval for displaying full range of events
    var years = latest_date.getFullYear() - earliest_date.getFullYear();
    var overview_interval_pixels = 100;
    var main_interval_pixels = overview_interval_pixels;
    var overview_interval_unit = Timeline.DateTime.YEAR;
    var main_interval_unit = Timeline.DateTime.YEAR;
    var median_date = earliest_date;
    if (years == 0 || years == 1) { 
      years = 1;
      var months = latest_date.getMonth() - earliest_date.getMonth();
      if (months < 2) {
        var days = latest_date.getDay() - earliest_date.getDay();
        if (days < 10) {
          main_interval_unit = Timeline.DateTime.DAY;
          overview_interval_unit = Timeline.DateTime.MONTH;
        } else {
          main_interval_unit = Timeline.DateTime.WEEK;
          overview_interval_unit = Timeline.DateTime.MONTH;
        }
      } else {
        main_interval_unit = Timeline.DateTime.MONTH;
      }
      overview_interval_pixels = Math.ceil(($('#timeline').width() - 50) / years) / 2;
      //overview_interval_unit = Timeline.DateTime.MONTH;
      main_interval_pixels = 100; //overview_interval_pixels / 5;
    }
    if (years > 10) { 
      median_date = new Date(earliest_date.getTime() + years*365*24*60*60*1000/2);
      overview_interval_pixels = Math.ceil(($('#timeline').width() - 50) / years) * 10;
      overview_interval_unit = Timeline.DateTime.DECADE; 
      main_interval_pixels = main_interval_pixels;
      //main_interval_unit = Timeline.DateTime.DECADE;
      main_interval_unit = Timeline.DateTime.YEAR;
    }
    bandInfos = [
      Timeline.createBandInfo({
        layout: 'overview',
        eventSource:    eventSource,
        eventPainter:   Timeline.OverviewEventPainter,
        //showEventText:  false,
        //trackHeight:    1.0,
        //trackGap:       0.2,
        width:          "10%", 
        //theme: theme,
        intervalUnit: overview_interval_unit, 
        //date:           d,
        date: latest_date, //median_date,
        intervalPixels: overview_interval_pixels
      }),
      Timeline.createBandInfo({
        width: "90%", 
        eventSource:    eventSource,
        //layout: 'compact',
        intervalUnit: main_interval_unit, 
        //date:           d,
        date: latest_date, //median_date,
        //date: earliest_date,
        theme: theme,
        eventSource: eventSource,
        eventPainter: Timeline.CompactEventPainter,
        eventPainterParams: {
          labelRightMargin: 2,
          iconWidth: 100,
          iconHeight: 100,
          iconLabelGap: 3,
          stackConcurrentPreciseInstantEvents: {
            limit: 5,
            moreMessageTemplate: "%0 others on this date",
            icon: "/site_media/images/collection_blank.gif", // default icon in stacks
            iconWidth: 100,
            iconHeight: 100
          }
        },
        intervalPixels: main_interval_pixels
      })
    ];
    bandInfos[0].syncWith = 1;
    bandInfos[0].highlight = true;
    // bandInfos[1].showEventText = false;
    // bandInfos[2].syncWith = 1;
    // bandInfos[2].highlight = true;
    tl = Timeline.create(document.getElementById("timeline"), bandInfos);
    //$('.timeline-event-bubble-title a').live('click', popupLink);
    //Timeline.OriginalEventPainter.prototype._showBubble = function(x, y, evt) {
    var originalShowBubble = Timeline.CompactEventPainter.prototype._showBubble;
    Timeline.CompactEventPainter.prototype._showBubble = function(x, y, evt) {
      if (evt.length > 1) {
        originalShowBubble.call(this, x, y, evt);
        return;
      }
       var url = evt[0].getLink();
       if (url && url != '') {
         if (evt[0].getClassName() && evt[0].getClassName().indexOf('popup_link') != -1) {
           updateState(evt[0].getLink(), '#dialog');
         } else {
           document.location.href = evt[0].getLink();
         }
       }
     };
    tl.showLoadingMessage();
    eventSource.loadJSON(items, document.location.href);
    tl.hideLoadingMessage();
    var date = Timeline.DateTime.parseGregorianDateTime(earliest_date);
    tl.getBand(0).scrollToCenter(date);
    $('#earliest_date').bind('click', function() {
      var date = Timeline.DateTime.parseGregorianDateTime(earliest_date);
      tl.getBand(0).scrollToCenter(date);
      return false;
    });
    $('#latest_date').bind('click', function() {
      var date = Timeline.DateTime.parseGregorianDateTime(latest_date);
      tl.getBand(0).scrollToCenter(date);
      return false;
    });
  }
  $('#member_form_table_id').hide();
/*
  $('#avatar_image').bind('mouseover', function() {
    //$('#avatar_rollover').show();
    $('#avatar_rollover').animate({opacity: 1}, 'fast');
  });
  $('#avatar_image').bind('mouseout', function() {
    //$('#avatar_rollover').hide();
    $('#avatar_rollover').animate({opacity: 0}, 'fast');
  });
*/
  // when the VIEW BY (or sort_by) select is changed, submit the search nav form
  $('#sort_by_id').bind('change', function() {
    $('#nav_form_id').submit(); // this is the generic form if it's community or member
    $('#market_search_form_id').submit(); // this is the marketplace form.
  });

  // setup search form for 'marketplace' nav --------------------------------
  //$('.' + $('#market_search_by_id').val() + '_controls').show();
  $('#market_search_form_id').bind('submit', function() {
    var price_input = $(this).find('#item_price_input_id').val();
    var sphere_input = $(this).find('#item_sphere_input_id').val();
    var sort_by = $('#sort_by_id').val();
    var search_by = $(this).find('#market_search_by_id').val();
    var keyword = $(this).find('#item_keyword_input_id').val();
    var completed = $(this).find('#completed_listings_id').attr('checked');
    var year_start = $(this).find('#item_date_start_input_id').val();
    var year_end = $(this).find('#item_date_end_input_id').val();
    if (completed) {
      price_input = price_input + '_completed';
    }
    if ((search_by == 'keyword') && (keyword != '')) {
      window.location = '/market/' + price_input + '/' + sphere_input + '/keyword/' + keyword + '/' + sort_by + '/';
    } else if (search_by == 'date') {
      if (year_start || year_end) {
        window.location = '/market/' + price_input + '/' + sphere_input + '/date/' + year_start + '-' + year_end + '/' + sort_by + '/';
      } else {
        window.location = '/market/' + price_input + '/' + sphere_input + '/' + sort_by + '/';
      }
    } else {
      window.location = '/market/' + price_input + '/' + sphere_input + '/' + sort_by + '/';
    }
    return false;
  });
  $('#market_search_by_id').bind('change', function() {
    // based on selection, hide inputs for other types
    if ($(this).val() == 'keyword') {
      $('.controls').hide();
      $('.keyword_controls').show();
      // focus the corresponding text input
      $('#item_keyword_input_id').focus();
      $('.market_' + $('#market_type_input_id').val()).show();
    } else if ($(this).val() == 'date') {
      $('.controls').hide();
      $('.date_controls').show();
    } else {
      $('.keyword_controls').hide();
    }
    $('.items_ctrl').show();
    return true;
  });
  // override the slideshow view type button action to insert flash SimpleViewer Pro
  $('#slideshow_close a').bind('click', function() {
    //$('.overlay').hide();
    //$('#flashContent').empty(); // unload the flash movie
    return false;
  });
  $('#flashContent').ready(function() {
    var flashvars = {};
    flashvars.galleryURL = window.location.pathname + "?view_type=xml";
    var params = {};
    params.allowfullscreen = true;
    params.allowscriptaccess = "always";
    params.bgcolor = "031C38";
    params.wmode = "transparent";
    swfobject.embedSWF("/site_media/simpleviewer.swf", "flashContent", "100%", "100%", "9.0.124", false, flashvars, params);
  });
/*
  $('#view_as_slideshow a').bind('click', function() {
    $('#dialog').data("width.dialog", 750).dialog('option', 'title', 'Slideshow');
    $('#dialog').empty().append('<div id="flashContent">no flash</div>').dialog('open');
    $('#dialog').ready(function() {
      var flashvars = {};
      flashvars.galleryURL = window.location.pathname + "?view_type=xml";
      var params = {};
      params.allowfullscreen = true;
      params.allowscriptaccess = "always";
      params.bgcolor = "031C38";
      params.wmode = "transparent";
      swfobject.embedSWF("/site_media/simpleviewer.swf", "flashContent", "100%", "100%", "9.0.124", false, flashvars, params);
      //$('.overlay').show();
    });
    return false;
  });
*/
  // each delete button on photo in detail_upload.html has its submit overridden
  $('.delete_photo_form').each(
    function() {  // hijack form submission to use ajax...
      $(this).bind('submit', photo_upload);
    });
  // ajax photo uploading...
  $('#photo_upload_form').bind('submit', photo_upload);
  function photo_upload() {
    $(this).ajaxSubmit({
      type: 'POST',
//      url: '/photos/xhr/upload', // override action with xhr version, but isn't working on firefox...
//      dataType: 'json',
//      contentType: 'application/json; charset=utf-8', 
      beforeSend: function() {
        $('#output').html('Saving').show();
        // select all options in id_photos before submitting
        //$("#id_photos option").attr("selected","selected");
        // ... except the dummy value
        //$("#photo_dummy_id").removeAttr("selected");
      }, 
      success: function(data) {
        //$('#photo_form_id').jqmHide();
        //console.log('data: ' + data);
        // if the ajaxForm method was passed an Options Object with the dataType
        // property set to 'json' then the first argument to the success callback
        // is the json data object returned by the server
        //alert('status: ' + data);
        $('#output').empty();
        //$('#output').append('<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>' + data.type + ': ' + data.message + '</li>');
        // append an <input> that correponds to the image ID
        $('#detail_photos_order').empty().append(data);
        $('#detail_photos_order').ready(function(){
          $(this).find('.popup_form').each(
            function() {  // hijack form submission to use ajax...
              $(this).bind('submit', photo_upload);
            });
          $(this).find('.delete_photo_form').each(
            function() {  // hijack form submission to use ajax...
              $(this).bind('submit', photo_upload);
            });
        });
        //if (data.type == "success") {
          // $('#imagelist_id').prepend('<li><img src="' + data.url + '" id="photo_' + data.id + '"/></li>');
          // $('#id_photos').append('<option value="' + data.id + '" selected="selected">' + data.id + '</option>');
          // $('#id_main_photo').append('<option value="' + data.id + '">' + data.id + '</option>');
        //}
      },
      resetForm: true,
      error: function(data, status, e) {
        // $('#photo_form_id').jqmHide();
        $('#output').html('xhr error').show();
        console.log(status + ': ' + e);
        jQuery.each(data, function(key, value) {
           console.log(key + ": " + value);
         });
      },
      timeout: 3000
    });
    return false;
  }
  // handle 'category' dropdown list change
  // hijax submit of 'add to marketplace' form
  $('#listing_edit_form').bind('submit', listing_edit);
  function listing_edit() {
    $(this).ajaxSubmit({
      type: 'POST',
      beforeSend: function() {
        $('#output').html('Saving').show();
      }, 
      success: function(data) {
        $('#output').empty();
        $('#trading_options').empty().append(data);
        $('#trading_options').ready(function(){
          // show/hide relevant input fields
          $(this).find('.popup_form').each(
            function() {  // hijack form submission to use ajax...
              $(this).bind('submit', listing_edit);
            });
        });
      },
      resetForm: true,
      error: function(data, status, e) {
        $('#output').html('xhr error').show();
        console.log(status + ': ' + e);
        jQuery.each(data, function(key, value) {
           console.log(key + ": " + value);
         });
      },
      timeout: 3000
    });
    return false;
  }
  // trades/popup/offer_review.html has some textarea content switching
  $('#id_accept_1').bind('change', updateOfferNotes);
  $('#id_accept_0').bind('change', updateOfferNotes);
  // set initially to 'accept' notes...
  $('#id_notes').val($('#id_accept_notes').html());
  $('.avatar_tips').cluetip({
    positionBy: 'bottomTop',
    width: 200,
    dropShadow: false,
    sticky: true,
    local: true,
    showTitle: false,
    clickThrough: true,
    mouseOutClose: true,
    closeText: ''
  });
  // setup cluetips for thumbnail content
  $('.tips').cluetip({
    positionBy: 'fixed',
    width: 200,
    topOffset: -100,
    leftOffset: 15,
    hoverIntent: {
      sensitivity:  3,
      interval:     50,
      timeout:      0
    },
    dropShadow: false,
    sticky: true,
    local: true,
    showTitle: false,
    clickThrough: true,
    mouseOutClose: true,
    //delayedClose: 5000,
    closeText: ''
  });
  // handle ajax_form submission
  $('.ajax_form').bind('submit', function() {
    alert('hi');
    return false;
  });
  Comments.attachHandlers();
  Dialog.attachHandlers();
});

