/* XXX: Tidy */
function fnSelect(objId) {
    fnDeSelect();
    if (document.selection) {
        var range = document.body.createTextRange();
        range.moveToElementText(document.getElementById(objId));
        range.select();
    }
    else if (window.getSelection) {
        var range = document.createRange();
        range.selectNode(document.getElementById(objId));
        window.getSelection().addRange(range);
    }
}

function fnDeSelect() {
    if (document.selection) {
        document.selection.empty();
    } else if (window.getSelection) {
        window.getSelection().removeAllRanges();
    }
}

ProductSearch = function (search_el_id, def_loc, tags_el_id) {

    this.ad_data = {id:null, type:null, tags:null, label:""};
    this.ad_location = def_loc.id;
    this.ad_location_name = def_loc.name;
    this.ad_id = null;
    this.ui_state = {};
    this.search_el = $("#" + search_el_id);
    this.tags_el = $("#" + tags_el_id);

    this.setup_product_ac = function () {
        var self = this;

        self.search_el
        .autocomplete({
            serviceUrl:'/api/product_autocomplete',
            onSelect: function(val, data) {
                $("#copy_html_text").empty();
                $(".copy-html").hide();
                $(".tag-text").remove();
                $("#message").fadeOut();
                $("#ac_error").fadeOut();
                var datum = data.split(".");
                self.ad_data.type = datum[0];
                self.ad_data.id = datum[1];
                self.ad_data.fbid = datum[2];
                self.ad_data.label = datum[3];
                self.ad_data.name = val;
                /* AC gives us category, make the UI piece appear */
                var tag_data = $('<span class="tag-text tag-readonly">'+ 
                    self.ad_data.label +'</span>');
                $("#prod_tag_list .add-tag-label").before(tag_data);
                self.ad_data.tags = [{name:self.ad_data.label}];
                self.tags_el.hide();
                $("#prod_tag_list").fadeIn();
                this.setup_tags_ac();
            },
         });

        self.search_el
        .bind("blur", function (e) {
            if ($(this).val() === "") {
                $(this).css("color", "#888");
                $(this).val("Enter an item here");
            }
        })
        .bind("click focus", function (e) {
            $(this).css("color", "#000");
            if ($(this).val().match(/^Enter.*/)) {
                $(this).val("");
            }
            else {
                $(this).select();
            }
        });
    };

    this.setup_tags_ac = function() {
        var self = this;
        /* total fucking hackery - will need cleanup */
        var add_tag_lbl_handler = function() {
            self.tags_el.fadeIn("slow", function() {
                self.tags_el.focus();
            });
            $("#add_tag_label").unbind("click");
            $(".add-tag-text").text("Cancel");
            $(".add-tag-text").click(function() {
                self.tags_el.fadeOut( function() {
                    $(".add-tag-text").text("Add Tag");
                    $("#add_tag_label").click(add_tag_lbl_handler);
                });
            });
        };

        $("#add_tag_label").click(add_tag_lbl_handler);

        self.tags_el
        .autocomplete({
            serviceUrl:'/api/tag_autocomplete',
            delimiter: /(,|;)\s*/,
            onSelect: function(val, data) {
                self.tags_el.fadeOut(function() {
                    var tag_data = $('<span class="tag-text">'+data+'</span>');
                    $("#prod_tag_list .add-tag-label").before(tag_data);
                    tag_data.click(function() {
                        var x  = confirm("Remove tag " + $(this).text() + "?");
                        if (x) {
                            $(this).remove();
                            for (var i in self.ad_data.tags) {
                                if (self.ad_data.tags[i].name == $(this).text()) {
                                    self.ad_data.tags.splice(i, 1);
                                    break;
                                }
                            }
                        };
                    });
                    if (self.ad_data.tags == null) {
                        self.ad_data.tags = [{name:data}];
                    } else {
                        self.ad_data.tags.push({name:data});
                    }
                    self.tags_el.val("");
                    $(".add-tag-text").text("Add Tag");
                    $("#add_tag_label").click(add_tag_lbl_handler);
            })},
         })
        self.tags_el
        .bind("click focus", function (e) {
            $(this).css("color", "#000");
            if ($(this).val().match(/^Please.*/)) {
                $(this).val("");
            }
            else {
                $(this).select();
            }
        });
        self.ad_data.tags = [];
    };

    this.error = function(msg, el) {
      var self = this;
      $("#ac_error .err-text").html(msg);
      $("#message").fadeOut();
      $("#ac_error").fadeOut(function() {
        $("#ac_error").fadeIn();
      });
    };

    this.message = function(msg) {
      var self = this;
      $("#ac_error").fadeOut();
      $("#message").fadeOut(function() {
        $("#message").html(msg);
        $("#message").fadeIn(150);
      });
    };

    /* Is the user logged in?  If not, pack ad state into
     * a cookie and pop up the RPX dialog */
    this.check_login = function() {
        var self = this;
        if (!$.cookie('vs_tkt')) {
          var cookie = {
              ui_state : {},
              data : self.ad_data,
              location : self.ad_location,
              location_name : self.ad_location_name
          };
          /* for each input, select or textarea tag in 
           * #dynamic, save its value under its id. */
          var extra = {};
          $("#dynamic input").each(function() {
              extra[$(this).attr('id')] = $(this).val();
          });
          $("#dynamic select").each(function() {
              extra[$(this).attr('id')] = $(this).val();
          });
          $("#dynamic textarea").each(function() {
              extra[$(this).attr('id')] = $(this).val();
          });
          $.extend(cookie.ui_state, extra);
          $.cookie('sm_state', $.toJSON(cookie));
          RPXNOW.show();
          return false;
        }
        return true;
    };

    this.update_ad_data = function(section, name, val) {
        var self = this;
        if (! self.ad_data[section])
            self.ad_data[section] = {};
        self.ad_data[section][name] = val;
    }

     this.save_core_basic_data = function() {
        var self = this;
        var cf = $(".core-field");
        var bf = $(".basic-field");
        var bfd = $(".basic-field-data");

        var l = cf.length;
        for (var i=0;i<l;i++) {
            self.update_ad_data("core", 
                cf[i].name.replace(/^details_/, ""), $(cf[i]).val());
        }
        l = bf.length;
        for (var i=0;i<l;i++) {
            self.update_ad_data("basic", 
                bf[i].name.replace(/^basic_/, ""), $(bf[i]).val());
        }
        l = bfd.length;
        for (var i=0;i<l;i++) {
            self.update_ad_data("basic", 
                bfd[i].id.replace(/^basic_/, ""), $(bfd[i]).text());
        }
        self.ad_data.description = $("#description").val();
    };


    this.sell = function() {
        var self = this;
        /* If this is a generic product (ie, autocomplete didn't match)
         * prompt the user to specify the type! */
        if (self.ad_data.tags == null) {
            $("#prod_tag_list").fadeIn();
            this.setup_tags_ac();
            return false;
        }

        $.ajax({
            type: "GET",
            url: "/index/sell",
            data: {
                  product: self.ad_data.id, 
                  type: self.ad_data.type, 
                  location: self.ad_location},
            dataType: "html",
            error: function (xhr, status, e) {
               self.error('Error submitting product: ' + status + '(' + e + ')');
            },
            success: function (res, status) {
              $("#dynamic").html(res);
              $(".ext-prod-info fieldset div").hide();
              $("#dynamic").fadeIn();
              self.upload = new AjaxUpload($("#upload_button"), {
                action: '/api/upload_image',
                name: 'imagefile',
                responseType: 'json',
                onSubmit: function(file, ext) {
                  if (self.ad_id == null) {
                    self.error("You must save your ad first");
                    return false;
                  }
                },
                onComplete: function(file, res) {
                  $("#uploaded_images").append('<img src="/images/'+res.imageid+'" />"');
                },
              });
              self.upload.disable();
              $("#upload_button").click(function() {
                  if (self.ad_id == null) {
                    self.error("You must save your ad before you can upload");
                  }
              });
              $(".field-data").editInPlace(
                  {callback: function(id, new_val,old_val, params) {
                      var data_name = id.replace(/^extra_/, "");
                      self.update_ad_data('extra', data_name, new_val);
                      return "<span class=\"field-data\" id=\"" + 
                          id + "\">" + new_val + "</span>";
              }});
              $(".ext-prod-info fieldset legend").click(function() {
                  $(this).parent().parent().parent().find("div").slideToggle("fast");
                  var icons = $(this).parent().parent().parent().find(".icon");
                  $.each(icons, function() {
                      if (this.src.search(/closed.png/) >= 0)
                          this.src = "/images/open.png";
                      else
                          this.src = "/images/closed.png";
                  });
              });
              /* Returned html has new buttons which need events */
              $("#savebutton").click(function (e) {
                 /* To save, must be logged in */
                 if (self.check_login()) {
                     var product = '';
                     if (self.ad_data.id != null) {
                        product = "fbid://"+self.ad_data.id;
                     }
                     if (self.ad_data.name == null) {
                        self.ad_data.name = self.search_el.val();
                     }
                     self.save_core_basic_data();
                     if (!self.ad_data.core.price.match(/^[0-9]+/)) {
                        self.error("You must enter a number for price")
                        $('html,body').animate({scrollTop: targetOffset}, 1000);
                        return false;
                     }
                     $.ajax({
                       type: "POST",
                       url: "/api/save_ad",
                       data: {
                          product: self.ad_data.id,
                          type: self.ad_data.type,
                          location: self.ad_location,
                          price: self.ad_data.core.price,
                          content: $.toJSON(self.ad_data),
                       },
                       dataType: "json",
                       success: function (res, status) {
                          self.ad_id = res.id;
                          self.upload.setData({id:res.id});
                          self.upload.enable();
                          self.message('Your ad has been saved! You can now upload images. Permalink: <a href="'+res.permalink+'">' + res.permalink + '</a> <a id="addthis-saved"></a>');
                          addthis.button('#addthis-saved', {}, {url: res.permalink, title: res.name + " for sale"});
                          $("#savearea").fadeOut();
                          $("#upload_img").attr('src', '/images/upload.png');
                       },
                       error: function (xhr, status, e) {
                          self.error('Error saving ad: ' + status + '(' + e + ')');
                       },
                     });
                 }
              });

              $("#copybutton").click(function (e) {
                    var product = '';
                     if (self.ad_data.id != null) {
                        product = "fbid://"+self.ad_data.id;
                     }
                     if (self.ad_data.name == null) {
                        self.ad_data.name = self.search_el.val();
                     }
                     self.save_core_basic_data();
                     if (!self.ad_data.core.price.match(/^[0-9]+/)) {
                        self.error("You must enter a number for price")
                        $('html,body').animate({scrollTop: targetOffset}, 1000);
                        return false;
                     }
                     $.ajax({
                       type: "POST",
                       url: "/api/html",
                       data: {
                          product: self.ad_data.id,
                          type: self.ad_data.type,
                          location: self.ad_location,
                          price: self.ad_data.core.price,
                          content: $.toJSON(self.ad_data),
                       },
                       dataType: "html",
                       success: function (res, status) {
                            $("#copy_html_text").empty();
                            $("#copy_html_text").html(res);
                            $("code").chili();
                            $(".copy-html").slideDown();
                            $("#close_copy_html").click(function() {
                                $("#copy_html_text").empty();
                                $(".copy-html").slideUp();
                            });
                            $("#select_copy_html").click(function() {
                                fnSelect('copy_html_text');
                            });
                       },

                    });

              });
              /* Reload the UI state, if there is anything there from
               * cookie load */
              for (var k in self.ui_state) {
                $("#dynamic #" + k).val(self.ui_state[k]);
              }
            }
        });
    };

    /* init */
    this.init = function() {
        var self = this;
        /* set up dummy console.log */
        if (typeof console === 'undefined') {
            var dummy = function() {};
            this.console = {info:dummy, log:dummy, warn:dummy, error:dummy};
        }

        this.setup_product_ac();
        /* If there is a cookie, resume state from it */
        var cookie = $.cookie('sm_state');
        if (cookie) {
            var cookie_data = $.evalJSON(cookie);
            self.ad_location = cookie_data.location;
            self.ad_location_name = cookie_data.location_name
            self.ad_data = cookie_data.data;
            self.ui_state = cookie_data.ui_state;
            /* State is loaded, resume the UI */
            $("#prod_search").val(self.ad_data.name);
            $(".loc-text").html(self.ad_location_name);
            /* Buy doesn't have any state, so assume we are resuming sell */
            self.sell();
            /* unset the cookie */
            $.cookie('sm_state', null);
        }
        $(".loc-text").suggestInPlace({callback: function(e, data) {
            self.ad_location = data.id;
            self.ad_location_name = data.name;
        }});
        $("#edit_loc_icon").click(function(e, data) {
            /* hackery?? perhaps, ask Niall about internals */
            $(".loc-text").trigger(e, data);
        });
        $("#buybutton").click(function (e) {
            $("#message").fadeOut();
            $("#ac_error").fadeOut();
            /* XXX: Search for product with this id, type etc */
            if ($("#prod_search").val().match(/^Enter.*/)
              || self.ad_data.id == null) {
                self.error("You must enter an item before continuing.");
                return false;
            }
            $.ajax({
                type: "GET",
                url: "/api/search",
                data: {
                  product: self.ad_data.id,
                  type: self.ad_data.type,
                },
                dataType: "json",
                success: function (res, status) {
                  if (res.products.length == 0) {
                      self.error("No results found, sorry.");
                      return false;
                  }
                  var i = 0;
                  while (i < res.products.length) {
                    $("#dynamic").append('Found <a href="/view/' + res.products[i].id + '">match</a> for $' + res.products[i].price + '<br/>');
                    i++;
                  }
                  $("#dynamic").fadeIn();
                },
                error: function (xhr, status, e) {
                   self.error('Error in search request: ' + status + '(' + e + ')');
                },
            });
        });
        $("#sellbutton").click(function (e) {
            $("#message").fadeOut();
            $("#ac_error").fadeOut();
            /* Some basic validation */
            if ($("#prod_search").val().match(/^Enter.*/)) {
                self.error( "You must enter an item before continuing.");
                return false;
            }
            if (self.ad_location == null) {
                self.error("You must enter a location before continuing.");
                return false;
            }
            /* Flip UI to sell state */
            self.sell();
        });
    }

    // call constructor
    this.init();
};
