<?xml version="1.0" encoding="UTF-8"?>
<Module>
    <ModulePrefs 
     title="__MSG_RSS__"
     description="Mash together and display up to five RSS feeds."
     thumbnail="http://storage.ning.com/topology/rest/1.0/file/get/3915025428?profile=original"
     directory_title="__MSG_RSS__"
     screenshot="http://os.ning.com/apps/rss/gfx/screenshot.png"
     title_url="http://os.ning.com/apps/rss/gadget.php"
     author="Ning"
     author_email="ninghelp@ning.com"
     author_affiliation="Ning, Inc."
     author_location="Palo Alto, CA, USA" >
        <Locale messages="http://os.ning.com/local/home/xncore/playground/597/907/os/apps/rss/locale/ALL_ALL.xml"/> 
        <Locale lang="en" messages="http://os.ning.com/local/home/xncore/playground/597/907/os/apps/rss/locale/ALL_ALL.xml"/> 
        <Locale lang="pt" messages="http://os.ning.com/local/home/xncore/playground/597/907/os/apps/rss/locale/pt_BR.xml"/> 
        <Require feature="opensocial-0.7"/>
        <Require feature="dynamic-height"/>
        <Require feature="settitle"/>
        <Require feature="views" />
        <Require feature="skins" />
    </ModulePrefs>
    <Content type="html" view="default,canvas,profile,home">
        <![CDATA[
        <script>
            appUrl = 'http://os.ning.com/local/home/xncore/playground/597/907/os/apps/rss'
        </script>
        <script>var viewer
var owner
var env
var config = {
    number:5,
    feeds:[]
}

//Not everyone has firebug... c'mon, go get it http://getfirebug.com
if (!console) {
  var console = {}
  console.log = function(text){
    return
  }
}

/* returns the style reference for a given css rule */
function getStyle (cssrule) {
    for (var i in document.styleSheets) {
        var styleRules = (document.styleSheets[i].rules) ? document.styleSheets[i].rules :
                         (document.styleSheets[i].cssRules) ? document.styleSheets[i].cssRules : [];
        for (var j=0; j<styleRules.length; j++){
            if (styleRules[j].selectorText.toUpperCase() == cssrule.toUpperCase()) {
                return styleRules[j];
            }
        }
    }
    return null;
}

/* Applies the skin from the Open Social container */
function updateCSS() {
    var bgColor     = gadgets.skins.getProperty(gadgets.skins.Property.BG_COLOR);
    var fontColor   = gadgets.skins.getProperty(gadgets.skins.Property.FONT_COLOR);
    var anchorColor = gadgets.skins.getProperty(gadgets.skins.Property.ANCHOR_COLOR);
    var gadgetStyle = getStyle('.gadget');
    var gadgetLinks = getStyle('.gadget a');
    var gadgetButtons = getStyle('input.button');
    gadgetStyle.style.color = fontColor;
    gadgetStyle.style.backgroundColor = bgColor;
    gadgetLinks.style.color = anchorColor;
    gadgetButtons.style.backgroundColor = anchorColor;
    var buttonContrast = Contrast.test(anchorColor, '#222222');
    if (buttonContrast == true) {
      gadgetButtons.style.color = '#222222';
    } else {
      gadgetButtons.style.color = '#FFFFFF';
    }
}

/*
  Color Contrast | Andrew Waer 
  Origins: http://juicystudio.com/services/colourcontrast.php

  Usage:
 
  // Contrast test for two colors
  // returns passing score OR false if test fails
  Contrast.test('#ffffff', '#000000');

  // find best match from one or two color sets
  // returns array containing two hex values OR false if no match
  Contrast.match('#ffffff', ['#000000', '#336699']);
  Contrast.match(['#ffffff', '#000000', '#336699']);
  Contrast.match(['#ffffff','#ffffcc'], ['#000000', '#336699']);
*/

var Contrast = function()
{
  // private functions and properties
  var _private =
  {
    min : { 
      'brightness': 125, 
      'difference': 500 
    },
    brightness : function(rgb1, rgb2){
      var b1 = ((rgb1.r * 299) + (rgb1.g * 587) + (rgb1.b * 114)) / 1000;
      var b2 = ((rgb2.r * 299) + (rgb2.g * 587) + (rgb2.b * 114)) / 1000;
      return Math.abs(Math.round(b1-b2));
    },
    difference : function(rgb1, rgb2){
      var diff = (Math.max(rgb1.r, rgb2.r) - Math.min(rgb1.r, rgb2.r)) + 
                 (Math.max(rgb1.g, rgb2.g) - Math.min(rgb1.g, rgb2.g)) + 
                 (Math.max(rgb1.b, rgb2.b) - Math.min(rgb1.b, rgb2.b));
      return Math.abs(Math.round(diff));
    },
    rgb : function(hex){
      hex = hex.replace('#','');
      var rgb = {
        r: parseInt(hex[0] + hex[1], 16),
        g: parseInt(hex[2] + hex[3], 16),
        b: parseInt(hex[4] + hex[5], 16)
      };
      return rgb;
    }
  };
  // public functions and properties
  var _public =
  {
    test : function(hex1, hex2){
      var rgb1 = _private.rgb(hex1);
      var rgb2 = _private.rgb(hex2);
      var brightness = _private.brightness(rgb1, rgb2);
      var difference = _private.difference(rgb1, rgb2);
      return (
        brightness >= _private.min.brightness && difference >= _private.min.difference
          ? ((brightness - _private.min.brightness) + (difference - _private. min.difference))
          : false
      );
    },
    match : function(hex1, hex2){
      var total_score, i, j;

      if (typeof hex1 == 'string') {hex1 = [hex1];}
      if (typeof hex2 == 'string') {hex2 = [hex2];}
      var best_match = { 
        score: 0,
        hex1:  null,
        hex2:  null
      };
      if (hex2 == null){
        for (i=0; i<hex1.length; i++){
          for (j=0; j<hex1.length; j++){
            total_score = _public.test(hex1[i], hex1[j]);
            if (total_score > best_match.score){
              best_match.score = total_score;
              best_match.hex1 = hex1[i];
              best_match.hex2 = hex1[j];
            }
          }
        }
      } 
      else {
        for (i=0; i<hex1.length; i++){
          for (j=0; j<hex2.length; j++){
            total_score = _public.test(hex1[i], hex2[j]);
            if (total_score > best_match.score){
              best_match.score = total_score;
              best_match.hex1 = hex1[i];
              best_match.hex2 = hex2[j];
            }
          }
        }
      }
      return (
        best_match.score > 0
        ? [ best_match.hex1, best_match.hex2 ]
        : false
      );
    }
  };
  return _public;
}();

/**
 * Request information about the gadget owner and viewer
 */
function requestInfo(callback) {
  var req = opensocial.newDataRequest();
  req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.OWNER), "owner");
  req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER), "viewer");
  req.send(callback);
}

function loadConfig(){
    console.log('loadConfig')
    var req = opensocial.newDataRequest();
    env = opensocial.getEnvironment();
    var fields = [ "updatesPerPage", "externalFeeds"];
    req.add(req.newFetchPersonAppDataRequest(opensocial.DataRequest.PersonId.OWNER, fields), "owner_data");
    req.send(configLoaded);
}

function configLoaded(response) {
    console.log('configLoaded')
    if (response.get("owner_data").hadError()) {
        alert('error loading configuration')
    } else {
        var data = response.get("owner_data").getData();
        var n = 0
        var f = []
        if (data[owner.getId()]) {
            n = data[owner.getId()].updatesPerPage
            var select = document.getElementById('n_updates')
            for (var i=0; i < select.options.length; i++) {
                if ((select.options.item(i)) && (select.options.item(i).value == n)) {
                    select.options.item(i).setAttribute('selected', 'true')
                    break
                }
            }
            f = data[owner.getId()].externalFeeds
            if (f != undefined ) { 
                if (typeof(f) == 'string'){
                    f = f.replace(/&#34;/g,'')
                    f = f.replace('[','')
                    f = f.replace(']','')
                    f = f.split(',')
                }
                for (var i=0; i<f.length; i++){
                    document.getElementById('external-feed'+i).value = f[i] 
                }
            }
            config.number = n
            config.feeds = f
        }
        loadList(n, f)
        if(viewer.isOwner()){
            document.getElementById('admin-bar').style.display = 'block'
            gadgets.window.adjustHeight()
        }
    }
    gadgets.window.adjustHeight()
};

function updateConfig(){
    console.log('updateSettings')
    var select = document.getElementById('n_updates')
    var updatesPerPage = select.options[select.selectedIndex].value
    var externalFeeds = []
    for (var i=0;i<5;i++){
        externalFeeds.push(document.getElementById('external-feed'+i).value)
    }
    var req = opensocial.newDataRequest();
    req.add(
        req.newUpdatePersonAppDataRequest("OWNER", "updatesPerPage", updatesPerPage),
        "set_data");
    req.add(
        req.newUpdatePersonAppDataRequest("OWNER", "externalFeeds", externalFeeds),
        "set_data");
    req.send(onConfigUpdated);
    return false
}

function onConfigUpdated(response)  {
    console.log('onSettingsUpdated')
    if (response.get("set_data").hadError()) {
      alert('Error updating shelf')
    } else {
        var select = document.getElementById('n_updates')
        var updatesPerPage = select.options[select.selectedIndex].value
        var externalFeeds = []
        for (var i=0;i<5;i++){
            externalFeeds.push(document.getElementById('external-feed'+i).value)
        }
        loadList(updatesPerPage, externalFeeds)
        toggleSettings()
    }
};

function loadList(numUpdates, feeds) {
    if (!numUpdates) numUpdates = config.number
    if (!feeds) feeds = config.feeds
    config.feeds = feeds
    for (var i=0; i<feeds.length; i++){
        document.getElementById('external-feed'+i).value = feeds[i] 
    }
    var url = appUrl+'/gadget.php';
    var params = {};
    var postdata = {
        action : 'list',
        external_feeds: feeds,
        begin: 0,
        end: numUpdates,
        user_id: owner.getId()
    };
    params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
    params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;
    gadgets.io.makeRequest(url+'?t='+ new Date().getTime()+'&'+gadgets.io.encodeValues(postdata), listLoaded, params);
}

function listLoaded(ret) {
    console.log('listLoaded')
    console.log(ret)
    var htmlout = ''
    var list = document.getElementById('rsslist')
    if(ret.errors && ret.errors.length>0){
        htmlout = 'Error - ' + ret.errors[0]
    } else {
        if (ret.data.result != 'success') {
            htmlout = '<li>' + ret.data.result + '</li>'
        } else {
            for ( var i=0; i < ret.data.list.length; i++) {
                htmlout += '<li class="rssitem"><a href="'+ret.data.list[i].link+'" class="rsstitle" target="_blank">' + ret.data.list[i].title + '</a><span class="timestamp">' + ret.data.list[i].timestamp + ' ('+ ret.data.list[i].service +')</span>'
                // htmlout += '<p class="rssbody">'+ ret.data.list[i].description + '</p>'
                htmlout += '</li>'
            }
            if (ret.data.list.length == 0){
                htmlout += '<li>No RSS updates yet.</li>'
            }
        }
    }
    list = document.getElementById('rsslist')
    if (ret.data.list.length > 0){ 
        link = document.getElementById('rsslink');
        link.innerHTML = '<a class="rss" href="'+ appUrl +'/gadget.php?action=list&fmt=rss&external_feeds='+escape(config.feeds)+'" target="_blank">RSS</a>';
        list.parentNode.appendChild(link)
    }
    list.innerHTML = htmlout
    gadgets.window.adjustHeight()
}

function init() {
    updateCSS();
    gadgets.window.adjustHeight();
    requestInfo(function (data) {
        viewer = data.get("viewer").getData();
        owner  = data.get("owner").getData();
        loadConfig()
        displayFooter()
    })
}

function displayFooter(){
    console.log('DisplayFooter')
    var whichfooter = (env.getDomain().indexOf('ning.com') == -1 ) ? 'others' : 'ning';
    var footer = document.getElementById(whichfooter + '-footer')
    if (footer) { footer.style.display = 'block' }
}


function toggleSettings(){
    var settings = document.getElementById('settingsform')
    var list = document.getElementById('rsslist')
    var editlink = document.getElementById('edit-link')
    if(settings.style.display == 'none') {
        editlink.innerHTML = "Cancel"
        settings.style.display = 'block'
        list.style.display = 'none'
    } else {
        editlink.innerHTML = "Settings"
        settings.style.display = 'none'
        list.style.display = 'block'
    }
    gadgets.window.adjustHeight()
    return false
}


gadgets.util.registerOnLoadHandler(init);</script>
        <style>.gadget {
    /* is replaced when the skin is applied */
    background-color: #fff;
    color: #999;
    padding:1px;
    padding-bottom:10px;
}
.gadget a {
    /* is replaced when the skin is applied */
    color: #00f;
} 

#admin-bar {
    text-align: right; 
}

a.edit, .edit {
    background:url(http://os.ning.com/local/home/xncore/playground/597/907/os/apps/rss/gfx/set_actions.gif) no-repeat 0 -192px;
    padding-left:17px;
}

.footer {
    clear:left;
    text-align:center;
}

.timestamp {
margin-left:1em;
}

li {
    list-style:none;
}

.rssitem {
    margin-top:10px;
    margin-bottom:0px;
    border-bottom:thin dotted;
    padding-bottom:5px;
}

.rss {
    background:url(http://os.ning.com/local/home/xncore/playground/597/907/os/apps/rss/gfx/set_tools.gif) no-repeat 0 -28px; 
    padding-left:17px;
}

/* Typography */
.gadget {font-size:12px !important;}
h1 {font-size:1.4em}
h2 {font-size:1.3em}
h3 {font-size:1.2em}
h4 {font-size:1.1em}
h1, h2, h3, h4, p {margin:.25em 0 .75em;}
input.text, select {margin:0 0 .75em;}

/* Spacing */
ul, ol, li {margin-left:0;padding-left:0;}
p.buttongroup {
	margin:0.5em 0;
	padding-top:.7em;
	border-top:1px solid #ccc;
	text-align:right;
	clear:both;
	overflow:visible !important;
}

a.button,
input.button {
	display:inline-block;
	width:auto;
	border:1px solid #aaa;
	font-size:1em;
	text-decoration:none;
	color:#333;
	overflow:visible;
	white-space:nowrap;
	line-height:1em!important;
}
/* ff2 */
a.button, x:-moz-any-link {
  padding:.28em .53em .226em;
}
input.button {
	padding:.2em .3em .15em;
}
/* ff3 */
a.button, x:-moz-any-link, x:default {
  padding:.4em .532em .34em;
}
input.button, x:-moz-any-link, x:default {
	padding:.21em .3em .16em;
}
/* safari: */
html[xmlns*=""] body:last-child a.button,
html[xmlns*=""] body:last-child input.button {
	padding:.35em .6em .45em;
}
/* ie: */
a.button {
  *margin-bottom:-.3em;
	*padding:.3em .57em;
}
input.button {
	*padding:.2em .5em .1em;
}
.wide {width:95%;}</style>
        ]]>
    </Content>
    <Content type="html" view="default,canvas,profile,home"><![CDATA[<div class="gadget"><div id="admin-bar" style="display:none;"><a class="edit" href="#" onclick="return toggleSettings()" id="edit-link">Settings</a></div>
<ul id="rsslist">
    <li>loading…</li>
</ul>
<form id="settingsform" style="display:none;">
    <h2>__MSG_how_many_posts__</h2>
    <select id="n_updates">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="5">5</option>
        <option value="10">10</option>
        <option value="20">20</option>
    </select>
    <h2>__MSG_external_feeds__</h2>
    <input type="text" id="external-feed0" class="text wide" value="" />
    <input type="text" id="external-feed1" class="text wide" value="" />
    <input type="text" id="external-feed2" class="text wide" value="" />
    <input type="text" id="external-feed3" class="text wide" value="" />
    <input type="text" id="external-feed4" class="text wide" value="" />
    <p class="buttongroup">
        <input type="submit" value="Save" class="primary-action button" onclick="return updateConfig();" />
        <input type="button" value="Cancel" class="button" onclick="return toggleSettings()" />
    </p>
</form>
<p id="rsslink"></p>

</div>]]></Content><Content type="html" view="canvas"><![CDATA[<div class="gadget"><p id="ning-footer" class="footer" style="display:none;"></p>

<p id="others-footer" class="footer" style="display:none;"> 
    __MSG_brought_to_you_by__ <a href="http://www.ning.com" target="_blank">__MSG_ning__</a>
    | <a href="http://about.ning.com/applicationstos.php" target="_blank">__MSG_terms_of_use__</a>
</p>
</div>]]></Content></Module>