/*
 * Immbro gallery widget
 *
 * @version 1.1 2009-10-16
 *
 * ==== to run default templated widget do:
 *
 * <head>
 *   ...
 *   <ling rel="stylesheet" type="text/css"
 *       href="http://new.immbro.com/media/share/gallery.css"/>
 *   <!-- or include your own CSS for it -->
 *   <script type="text/javascript"
 *       src="http://new.immbro.com/media/share/gallery.js"></script>
 *   <script type="text/javascript">
 *       immbro.gallery('user', 'Gallery tag name', 'gallery-element');
 *   </script>
 *   ...
 * </head>
 * <body>
 *   ...
 *   <div id="gallery-element"></div>
 *
 * ==== to run widget with custom template do:
 *
 * <head>
 *   ...
 *   <script type="text/javascript"
 *       src="http://new.immbro.com/media/share/gallery.js"></script>
 *   <script type="text/javascript">
 *       immbro.gallery('user', 'Gallery tag name').renderTemplate('gallery-element');
 *   </script>
 *   ...
 * </head>
 * <body>
 *   ...
 *   <div id="gallery-element">
 *       For addition imformation about templates see jstemplates.js
 *   </div>
 */

if (! window.immbro) immbro = {};

immbro.path_api_gallery    = "http://www.immbro.com/api/brochures.json";
immbro.path_api_jstemplate = "http://www.immbro.com/media/share/jstemplate.js";

/**
 * immbro.gallery() or new immbro.gallery() -- creates new gallery
 * immbro.gallery(element_id) -- finds gallery, rendered in element last
 * immbro.gallery(user, tag) -- creates gallery and calls load(user, tag)
 * immbro.gallery(user, tag, element_id) -- creates gallery, 
 *   calls load(user, tag) and render(element_id)
 */
immbro.gallery = function ()
{
    if (this == window || this == immbro) {
        var obj = new immbro.gallery;
        return obj.constructor.apply(obj, arguments);
    }
    this._onLoad = null;
    if (arguments.length == 1) {
        // immbro.gallery(element_id)
        var obj = immbro.gallery.galleries[arguments[0]];
        obj.element = document.getElementById(arguments[0]);
        return obj;
    }
    if (arguments.length > 1)
        // immbro.gallery(user, tag)
        this.load(arguments[0], arguments[1]);
    if (arguments.length > 2)
        // immbro.gallery(user, tag, element_id)
        this.render(arguments[2]);
    return this;
};

// element-id => gallery-obj
immbro.gallery.galleries = {};

/**
 * Loads script from {url} by creating <script> tag
 */
immbro.loadScript = function (url)
{
    var stag = document.createElement('script');
    stag.type = 'text/javascript';
    stag.src  = url;
    var body = document.getElementsByTagName('body')[0];
    if (body)
        body.appendChild(stag);
    else
        window.setTimeout(function(){
            immbro.loadScript(url);
        }, 500);
};
/**
 * Loads random brochure for [user] with [tag]
 */
immbro.gallery.prototype.load = function (user, tag)
{
    this.error   = null;
    this._onLoad = null;
    this.user    = user;
    this.tag     = tag;
    var callback = 'immbro_callback' + Math.floor(Math.random()*10000);
    var gallery  = this;
    window[callback] = function(json) { gallery.setData(json); };
    var url = immbro.path_api_gallery + '?' +
        'username=' + encodeURIComponent(user) + '&' +
        'tag='  + encodeURIComponent(tag) + '&' +
        'jsonp=' + callback + '&random=' + Math.floor(Math.random()*10000);
    immbro.loadScript(url);
    return this;
};
/**
 * loads new brochure from gallery and renders it into element
 */
immbro.gallery.prototype.reload = function (element)
{
    this.brochure = null;
    this.load(this.user, this.tag);
    this.render(element);
    return this;
}
/**
 * Events system.
 * Avaliable events: data-load, render, error
 */
immbro.gallery.prototype.bind = function (event, func)
{
    if (! this.events)
        this.events = {};
    if (! this.events[event])
        this.events[event] = [];
    this.events[event].push(func);
}
immbro.gallery.prototype.trigger = function (event, arg)
{
    if (this.events && this.events[event])
        for (var i = 0; i < this.events[event].length; i++)
            this.events[event][i].apply(this, [arg]);
}
immbro.gallery.prototype.unbind = function (event)
{
    if (this.events)
        this.events[event] = [];
}
/**
 * reports error
 */
immbro.gallery.prototype.reportError = function (errors)
{
    if (typeof(errors) == 'object') {
        this.error = '';
        for (var key in errors) {
            this.error += key + ": " + errors[key].join(" ") + "\n";
        }
    }
    else 
        this.error = errors;
    
    gallery.trigger("error", errors);
}
/**
 * callback to set brochure data
 */
immbro.gallery.prototype.setData = function (data)
{
    if (data.errors || data.total == 0) {
        this.reportError(data.errors || "No items to display");
        return;
    }
    this.brochure = data.results[0].brochures[0];
    this.brochure.property = data.results[0].property;

    this.trigger("data-load", data);
    
    return this;
};
/**
 * formats [price] for [currency] in immbro.formatPrice_formats keys,
 * adds 'pw' if [rent]
 */
immbro.formatPrice = function (price, currency, rent)
{
    var result;
    if (immbro.formatPrice_formats[currency])
        result = immbro.formatPrice_formats[currency](price);
    else
        result = immbro.formatPrice_formats._default(price, currency);
    if (rent)
        result += ' <abbr title="per week">pw</abbr>';
    return result;
}

immbro.formatPrice_formats = {
  GBP: function(price)
  {
      if (! price) return '';
      var t = [];
      while (price.length > 3) {
          t.unshift(price.substr(price.length - 3, 3));
          price = price.substr(0, price.length - 3);
      }
      if (price) t.unshift(price);
      return '&pound;' + t.join(',');
  },
  _default: function(price, currency)
  {
      return price + currency;
  }
};
/**
* renders default template in #element_id
*/
immbro.gallery.prototype.render = function (element_id)
{
    if (this.error) {
        document.getElementById(element_id).innerHTML = 
            '<p class="error">Sorry, some error occured</p><!-- ' + this.error + ' -->';
        return;
    }
    if (! this.brochure) {
        this.bind("data-load", function(data) {
            this.render(element_id);
        });
        return; // render when loaded
    }
    immbro.gallery.galleries[element_id] = this;

    this.element = document.getElementById(element_id);
    var landscape = [];
    for (var i = 0; i < this.brochure.photos.length; i++)
        if (this.brochure.photos[i].width > this.brochure.photos[i].height)
            landscape.push(this.brochure.photos[i]);
    this.brochure.photos = landscape;

    // params for photos slide
    this.active_photo = 0;
    this.getMainPhotoElement = function(container) {
        var imgs = container.getElementsByTagName('img');
        for (var i = 0; i < imgs.length; i++)
            if (imgs[i].className == 'main-photo')
                return imgs[i];
    };
    this.active_photo_size = '300x300';

    var b = this.brochure;
    var p = this.brochure.property;
    this.element.className += ' immbro-brochure';
    this.element.innerHTML =
        '<h3>' +
            [p.area, p.street, p.type.display, p.postcode, p.postcode2,
                p.countof_bedroom + ' Bed' + (p.countof_bedroom == 1 ? '' : 's'),
                p.sqm_floor_space + ' m&sup2'
            ].join(' | ') +
        '</h3>' +
        '<div class="photos">' +
            '<img class="main-photo" src="' +
                b.photos[0].path + '/300x300/Photo' + b.photos[0].extension +
            '" onclick="immbro.gallery(\'' + element_id + '\').nextPhoto()"/>' +
            '<ul>' +
                (b.photos[0] ?
                '<li><img src="' + 
                    b.photos[0].path + '/300x300/Photo' + b.photos[0].extension +
                '" onclick="immbro.gallery(\'' + element_id + '\').showPhoto(0)"/></li>'
                :'') +
                (b.photos[1] ?
                '<li><img src="' +
                    b.photos[1].path + '/300x300/Photo' + b.photos[1].extension +
                '" onclick="immbro.gallery(\'' + element_id + '\').showPhoto(1)"/></li>'
                :'') +
                (b.photos[2] ?
                '<li><img src="' +
                    b.photos[2].path + '/300x300/Photo' + b.photos[2].extension +
                '" onclick="immbro.gallery(\'' + element_id + '\').showPhoto(2)"/></li>'
                :'') +
            '</ul>' +
        '</div>' +
        (b.rent_long.status.value || b.rent_short.status.value ?
              '<p>To let: ' +
              (b.rent_long.status.value ?
              '<span>Long-term ' + immbro.formatPrice(b.rent_long.price, b.currency.value, true) +
                  ' ' + b.rent_long.furnishing.display + '.</span>'
              :'') +
              (b.rent_short.status.value ?
              '<span>Short-term ' + immbro.formatPrice(b.rent_short.price, b.currency.value, true) +
                  ' ' + b.rent_short.furnishing.display + '.</span>'
              :'') +
              '</p>'
        :'') +
        (b.sale.status.value ?
            '<p>For sale: ' + b.sale.status.display + ' ' +
                immbro.formatPrice(b.sale.price, b.currency.value) +
            '</p>'
        :'') +
        '<p class="refs"><a href="' + b.url_page.overview +
            '">View full details</a> including <a href="' +
            b.url_page.photos + '">Photos</a>, <a href="' +
            b.url_page.floorplans + '">Floor plans</a> and <a href="' +
            b.url_page.location + '">Location map</a>.</p>';
            
    this.trigger("render", element_id);
    return this;
};

// current photo shown, for slideshow
immbro.gallery.prototype.active_photo = 0;
// main photo size for slideshow
immbro.gallery.prototype.active_photo_size = '';
// returns main photo IMG element from container element for slideshow
immbro.gallery.prototype.getMainPhotoElement = function(element) {};

/**
 * show photo number ind (from 0)
 */
immbro.gallery.prototype.showPhoto = function (ind)
{
    if (ind < 0) 
        ind = this.brochure.photos.length + ind;
    if (ind >= this.brochure.photos.length) 
        ind = ind - this.brochure.photos.length;
    var photo = this.brochure.photos[ ind ];
    var img = this.getMainPhotoElement(this.element);
    this.active_photo = ind;
    img.src = photo.path + '/' + this.active_photo_size + '/Photo' + photo.extension;
}
/**
 * show next photo, uses active_photo member
 */
immbro.gallery.prototype.nextPhoto = function()
{
    this.showPhoto(this.active_photo + 1);
}
/**
 * loads jstemplate library and renders template from #element_id
 */
immbro.gallery.prototype.renderTemplate = function (element_id)
{
    if (this.error) {
        document.getElementById(element_id).innerHTML = 
            '<p class="error">Sorry, some error occured</p><!-- ' + this.error + ' -->';
        return;
    }
    if (! this.brochure) {
        this.bind("data-load", function(data) {
            this.renderTemplate(element_id);
        });
        return; // render when loaded
    }
    immbro.loadScript(immbro.path_api_jstemplate);
    var gallery = this;
    var exec_when_jst_loaded = function() {
        if (! window.jst) {
            window.setTimeout(exec_when_jst_loaded, 100);
            return;
        }
        jst(element_id).render(gallery.brochure);
        gallery.trigger("render", element_id);
    };
    exec_when_jst_loaded();
    return this;
};


