var BrowserDetect = {
init: function () {
        this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
        this.version = this.searchVersion(navigator.userAgent)
          || this.searchVersion(navigator.appVersion)
          || "an unknown version";
        this.OS = this.searchString(this.dataOS) || "an unknown OS";
      },
searchString: function (data) {
                for (var i=0;i<data.length;i++) {
                  var dataString = data[i].string;
                  var dataProp = data[i].prop;
                  this.versionSearchString = data[i].versionSearch || data[i].identity;
                  if (dataString) {
                    if (dataString.indexOf(data[i].subString) != -1)
                      return data[i].identity;
                  }
                  else if (dataProp)
                    return data[i].identity;
                }
              },
searchVersion: function (dataString) {
                 var index = dataString.indexOf(this.versionSearchString);
                 if (index == -1) return;
                 return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
               },
dataBrowser: [
             {
string: navigator.userAgent,
        subString: "Chrome",
        identity: "Chrome"
             },
             {   string: navigator.userAgent,
subString: "OmniWeb",
           versionSearch: "OmniWeb/",
           identity: "OmniWeb"
             },
             {
string: navigator.vendor,
        subString: "Apple",
        identity: "Safari",
        versionSearch: "Version"
             },
             {
prop: window.opera,
      identity: "Opera"
             },
             {
string: navigator.vendor,
        subString: "iCab",
        identity: "iCab"
             },
             {
string: navigator.vendor,
        subString: "KDE",
        identity: "Konqueror"
             },
             {
string: navigator.userAgent,
        subString: "Firefox",
        identity: "Firefox"
             },
             {
string: navigator.vendor,
        subString: "Camino",
        identity: "Camino"
             },
             {   // for newer Netscapes (6+)
string: navigator.userAgent,
        subString: "Netscape",
        identity: "Netscape"
             },
             {
string: navigator.userAgent,
        subString: "MSIE",
        identity: "Explorer",
        versionSearch: "MSIE"
             },
             {
string: navigator.userAgent,
        subString: "Gecko",
        identity: "Mozilla",
        versionSearch: "rv"
             },
             {     // for older Netscapes (4-)
string: navigator.userAgent,
        subString: "Mozilla",
        identity: "Netscape",
        versionSearch: "Mozilla"
             }
      ],
        dataOS : [
        {
string: navigator.platform,
        subString: "Win",
        identity: "Windows"
        },
        {
string: navigator.platform,
        subString: "Mac",
        identity: "Mac"
        },
        {
string: navigator.userAgent,
        subString: "iPhone",
        identity: "iPhone/iPod"
        },
        {
string: navigator.platform,
        subString: "Linux",
        identity: "Linux"
        }
      ]

};


var is_ie = false;

BrowserDetect.init();
if (BrowserDetect.browser == 'Explorer') {
  switch(BrowserDetect.version) {
    case 8:
      is_ie = true;
      break;
    case 7:
      is_ie = true;
      break;
    case 6:
      is_ie = true;
      break;
  }
}

if(typeof console === "undefined") {
  console = { log: function() { } };
}

PB = window.PB || {};

PB.Widget = function(id, data, options) {
    this.init(id, data, options);
};

PB.Widget.prototype = function() {
    return {
      assetRootURL: 'http://www.punchbowl.com/',
      hasLocalStyleElement: true,

      init: function(id, data, options) {
        this.id = id;
        if (data) {
          this.data = data;
        }
        this.options = options || {};
      },

      render: function() {
        addRemoteStylesheet(this.getRemoteStylesheet());

        var replaceID = this.options.replaceID;
        if (this.options.replaceID) {
          delete this.options.replaceID;
        } else if (this.widget) {
          replaceID = this.widget.id;
        }

        if (this.hasLocalStyleElement) {
          this.replaceStyleElement();
        }

        if (replaceID) {
          var element = document.getElementById(replaceID);
          var content = this.getWidgetHTML();
          element.innerHTML = content;
        } else {
          document.write(this.getWidgetHTML());
        }

        this.widget = document.getElementById(this.getDOMID());
      },

      replaceStyleElement: function() {
        this.removeStyleElement();
        this.setStyleElement();
      },

      setStyleElement: function() {
        this.styleElement = addLocalStylesheet(this.getThemeCSS());
      },

      removeStyleElement: function() {
        if (this.styleElement) {
          this.styleElement.parentNode.removeChild(this.styleElement);
        }
      },

      getSelectorPrefix: function() {
        return ' #' + this.getDOMID() + ' ';
      }
    }
}()


/* RTC Widget */

PB.RTCWidget = function(id, data, options) {
  PB.Widget.call(this, id, data, soft_merge_hashes(options, { shape: 'skyscraper' }));
}

PB.RTCWidget.prototype = merge_hashes(new PB.Widget(), {
  hasLocalStyleElement: true,

  getRemoteStylesheet: function() {
    return this.assetRootURL + 'stylesheets/widgets/rtc_widgets.css';
  },
  getWidgetHTML: function() {
    return PBS.templates.daily_rtc(merge_hashes(this.data, { urlBase: this.assetRootURL, text: truncate(this.data.text, this.getTruncateLength()), id: this.getDOMID(), main_class: this.getMainClass() }));
  },
  getDOMID: function() {
    return "mpb_rtc_widget_" + this.id;
  },
  getMainClass: function() {
    var val;
    switch(this.options.shape) {
      case 'box_ad':
        val = 'box_ad';
        break;
      case 'skyscraper':
        val = 'skyscraper';
        break;
      default:
        val = 'skyscraper';
    }
    return val;
  },
  getTruncateLength: function() {
    var length;
    switch (this.getMainClass()) {
      case 'box_ad':
        length = 120;
        break;
      default:
        length = 170;
    }
    return length;
  },
  getSelectorPrefix: function() {
    return ' #' + this.getDOMID() + '.mpb_rtc_widget ';
  },
  getThemeCSS: function() {
    var line_height = '1.2em';
    var text_align = 'left !important';
    var text_color = this.data.text_color + ' !important';
    var font_size = '13px !important';
    var font_family = 'Arial !important';
    var top_curves = "-moz-border-radius-topleft: 8px; -moz-border-radius-topright: 8px; -webkit-border-top-left-radius: 8px; -webkit-border-top-right-radius: 8px;";
    var bottom_curves = "-moz-bo  rder-radius-bottomleft: 8px; -moz-border-radius-bottomright: 8px; -webkit-border-bottom-left-radius: 8px; -webkit-border-bottom-right-radius: 8px;";
    var top_gradient = "background-image: -webkit-gradient(linear, 0% 0%, 0% 95%, from(rgba(255, 255, 255, 0.3)), to(rgba(255, 255, 255, 0))); background: -moz-linear-gradient(top left, rgba(255,255,255,0.3), rgba(255,255,255,0));";

    var css = "";
    css += ".mpb_rtc_widget div { padding: 0px; margin: 0px; }\n";

    var rulePrefix = this.getSelectorPrefix();
    var standardDefs = [];

    standardDefs.push("p { margin: 0px !important; }");
    standardDefs.push(".top div { font-size: " + font_size + "; font-family: " + font_family + "; line-height: " + line_height + "; }");
    standardDefs.push(".top div { font-size: " + font_size + "; font-family: " + font_family + "; line-height: " + line_height + "; }");
    standardDefs.push("{ text-align: " + text_align + "; }");
    standardDefs.push(".box_ad .header .image { width: 100px; height: 100px; }");
    standardDefs.push(".skyscraper .header .image { width: 120px; height: 120px; margin: 0px auto; }");
    standardDefs.push(".box_ad { width: 300px; }");
    standardDefs.push(".skyscraper { width: 160px; }");
    standardDefs.push(".colored_text { font-size: " + font_size + "; text-align: " + text_align + "; color: " + text_color + "; }");
    standardDefs.push("a.colored_text { text-decoration: underline; }");
    standardDefs.push("a.colored_text:hover { text-decoration: none; }");
    standardDefs.push(".colored_text p { color: " + text_color + "; }");
    standardDefs.push(".skyscraper .header { margin: 0px; padding: 0px; }");
    standardDefs.push(".skyscraper .top .header p.date { width: 140px !important; }");
    standardDefs.push(".skyscraper .top .header p.name { width: 140px !important; }");
    standardDefs.push(".box_ad .header { margin: 0px; padding: 26px 0px 0px 0px; }");
    standardDefs.push(".image { margin: 0px; padding: 0px; }");
    standardDefs.push(".top { " + top_curves + " " + top_gradient + "}");
    standardDefs.push(".top .header { text-align: " + text_align + "; }");
    standardDefs.push(".top .header .date { font-size: " + font_size + "; color: " + text_color + "; }");
    standardDefs.push(".top .text { padding: 4px 0px 4px 0px; }");
    standardDefs.push(".top .text .custom { font-size: " + font_size + "; margin: 0px !important; padding: 0px 0px 0px 1px !important; color: " + text_color + "; text-align: " + text_align + "; }");
    standardDefs.push(".box_ad .top .header p.date { margin-left: 130px !important; }");
    standardDefs.push(".box_ad .top .header p.name { margin-left: 130px !important; }");
    standardDefs.push(".box_ad .bottom { height: 29px; }");
    standardDefs.push(".top .header p.name { margin-top: 2px !important; }");
    standardDefs.push(".top .text p.read_more { text-align: " + text_align + "; margin-top: 5px !important; }");
    standardDefs.push(".top .text .read_more a.colored_text { text-align: " + text_align + "; color: " + text_color + "; text-decoration: underline !important; }");
    standardDefs.push(".top .text .read_more a.colored_text:hover { text-decoration: none !important; }");
    standardDefs.push(".top .text .read_more a:link { font-weight: normal; text-align: " + text_align + "; color: " + text_color + "; }");
    standardDefs.push(".top .day_links { margin: 4px auto 0px auto; padding: 0px; }");
    standardDefs.push(".bottom { " + bottom_curves + "; font-family: " + font_family + "; height: auto; font-size: 12px !important; background-color: #843F58; background-image: none; }");
    standardDefs.push(".bottom a { background: none; line-height: 14px; }");
    standardDefs.push(".bottom a.get_own { display: block; font-weight: normal; color: white; font-family: " + font_family + "; font-size: 12px !important; text-decoration: none !important; padding-bottom: 5px; }");
    standardDefs.push(".bottom a.get_own:hover { text-decoration: underline !important; }");

    for (cssRule in standardDefs) {
      var fullCSSRule = rulePrefix + standardDefs[cssRule] + "\n";
      css += fullCSSRule;
    }

    css += "* html img { background-image: expression(this.runtimeStyle.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\"' + this.src + '\", sizingMethod=\"image\")', this.runtimeStyle.backgroundImage = 'none', this.src = '/images/transparentpixel.gif'); }"
    return css;
  }
});

PB.RTCWidget.todays_widgets = [];
PB.RTCWidget.ds = {};

function beginningOfToday() {
  return new Date((new Date()).getFullYear(), (new Date()).getMonth(), (new Date()).getDate());
}

// Returns a string which is the UTC getTime() of the date given
function getDateString(date) {
  if (date.year) {
    // Convert JSON date info into a JS Date object
    date = new Date(date.year, date.month - 1, date.day);
  }
  return date.getTime().toString();
}

// Adds the widget to the DOM
PB.RTCWidget.create = function(options) {
  soft_merge_hashes(options, { date: beginningOfToday() })
  var day_data = PB.RTCWidget.ds[getDateString(options.date)];
  if (day_data) {
    var widget = new PB.RTCWidget(PB.RTCWidget.todays_widgets.length + 1, day_data, options);
    PB.RTCWidget.todays_widgets.push(widget);
    widget.render();
  } else {
    console.log("Error: The day's RTC data was not loaded. [" + options.date + "]")
  }
}

// Sets up the data for a Today's RTC widget
function setupRTCData(data, start_date) {
  if (!data) {
    return false;
  }

  start_date = start_date ? start_date : beginningOfToday();
  var tomorrow = new Date(start_date);
  tomorrow.setTime(tomorrow.getTime() + (1000 * 3600 * 24));
  var yesterday = new Date(start_date);
  yesterday.setTime(yesterday.getTime() - (1000 * 3600 * 24));

  data.today_year      = start_date.getFullYear();
  data.today_month     = start_date.getMonth() + 1;
  data.today_day       = start_date.getDate();

  data.tomorrow_year   = tomorrow.getFullYear();
  data.tomorrow_month  = tomorrow.getMonth() + 1;
  data.tomorrow_day    = tomorrow.getDate();

  data.yesterday_year  = yesterday.getFullYear();
  data.yesterday_month = yesterday.getMonth() + 1;
  data.yesterday_day   = yesterday.getDate();

  var date_string = getDateString(start_date);

//  console.log('Wrote in PB.RTCWidget.ds["' + date_string + '"] = ' + data);
  PB.RTCWidget.ds[date_string] = data;
}


/* Profile Widget */

PB.Widget.profileWidgets = {};

PB.ProfileWidget = function(id, data) {
  PB.Widget.call(this, id, data);
}

PB.ProfileWidget.prototype = merge_hashes(new PB.Widget(), {
  getRemoteStylesheet: function() {
    return this.assetRootURL + 'stylesheets/widgets/profile_widgets.css';
  },
  getWidgetHTML: function() {
    return JST.profile_widget(merge_hashes(this.data, { urlBase: this.assetRootURL }));
  },
  getDOMID: function() {
    return "mpb_profile_widget_" + this.id;
  },
  getThemeCSS: function() {
    this.theme = merge_hashes({
      preferencesColor: '#2A4863',
      tileImage: this.assetRootURL + 'images/widgets/tiles_bg_stripes_75x75.jpg'
    }, this.options);

    var css = "";
    css += this.getSelectorPrefix() + ".preferences p { color: " + this.theme.preferencesColor + "; }";
    css += this.getSelectorPrefix() + ".tiled { background: transparent url(" + this.theme.tileImage + ") repeat top left; }";
    return css;
  }
});

// Sets up the data for a Profile widget
function createProfileWidget(data) {
  // Create the widget, but do not render it yet
  PB.Widget.profileWidgets[data.id] = new PB.ProfileWidget(data.id, data);
}

// Adds the widget to the DOM
function renderProfileWidget(id, options) {
  PB.Widget.profileWidgets[id].render(options);
}


/***********/
/* Helpers */
/***********/

function addRemoteStylesheet(href) {
  var link_element = document.createElement("link");
  link_element.href = href;
  link_element.rel = "stylesheet";
  link_element.type = "text/css";
  document.getElementsByTagName("head")[0].appendChild(link_element);
}

var alreadyLoaded = false;
var addLocalStylesheet = function(content) {
  var style_tag = document.createElement("style");
  style_tag.type = "text/css";
  if (is_ie) {
      style_tag.styleSheet.cssText = content;
  } else {
      var inner = document.createDocumentFragment();
      inner.appendChild(document.createTextNode(content));
      style_tag.appendChild(inner);
  }

  function addToHead(style_element) {
      document.getElementsByTagName("head")[0].appendChild(style_element);
  }

  if (!is_ie || alreadyLoaded) {
      addToHead(style_tag);
  } else {
    window.attachEvent("onload",
    function() {
        alreadyLoaded = true;
        addToHead(style_tag);
    })
  }
  return style_tag;
}

function merge_hashes(destination, source) {
  for (var property in source)
    destination[property] = source[property];
  return destination;
};

function soft_merge_hashes(destination, source) {
  for (var property in source) {
    if (!destination[property]) {
      destination[property] = source[property];
    }
  }
  return destination;
}

var truncate = function (str, limit) {
	var bits, i;
	if ('string' !== typeof str) {
		return '';
	}
	bits = str.split('');
	if (bits.length > limit) {
		for (i = bits.length - 1; i > -1; --i) {
			if (i > limit) {
				bits.length = i;
			}
			else if (' ' === bits[i]) {
				bits.length = i;
				break;
			}
		}
		bits.push('...');
	}
	return bits.join('');
};
