1. (function ($) {
  2.    
  3.     window.Settings = Backbone.Model.extend({
  4.         defaults: {
  5.             "layout":       "list",
  6.             "classname":    $("#DocClassname").val(),
  7.             "fkid":         $("#DocFkid").val(),
  8.             "isNode":       null,
  9.             "addUrl":       "/admin/docs/add"
  10.         }
  11.     });
  12.    
  13.     window.Doc = Backbone.Model.extend({
  14.         urlRoot: "/docs/",
  15.         url:    function(){
  16.             var base = "/docs";
  17.             if(this.isNew()) return base + ".json";
  18.             return base + (base.charAt(base.length - 1) == "/" ? "" : "/") + this.id + ".json";
  19.         }
  20.     });
  21. /**************************************************************/
  22. /*          EVENTS
  23. /**************************************************************/
  24.     var aggregator = {};
  25.     _.extend(aggregator, Backbone.Events);
  26.    
  27.     aggregator.on("fileUpdated", function(model){
  28.         if(app.libraryCollection && app.galleryCollection){
  29.             libraryModel = app.libraryCollection.get(model.get("id"));
  30.             galleryModel = app.galleryCollection.get(model.get("id"));
  31.             libraryModel.set(model.attributes);
  32.             galleryModel.set(model.attributes);
  33.         }  
  34.     });
  35.  
  36.  
  37.    
  38. /**************************************************************/
  39. /*          LIBRARY COLLECTION (ALL FILES)
  40. /*          GALLERY COLLECTION (ATTACHED ONLY)
  41. /**************************************************************/
  42.  
  43.     window.LibraryCollection = Backbone.Collection.extend({
  44.         model:      Doc,
  45.         url:        "/docs/index.json",
  46.        
  47.         parse: function(response) {
  48.             this.page = response.page;
  49.             this.limit = response.limit;
  50.             this.count = response.count;
  51.             data = [];
  52.             _.each(response.models, function(obj){
  53.                 data.push(obj.Doc);
  54.             });
  55.             return data;
  56.         }
  57.    
  58.     });
  59.    
  60.     window.GalleryCollection = Backbone.Collection.extend({
  61.         model:      Doc,
  62.         url:        function(){
  63.             classname = appSettings.get("classname");
  64.             fkid = appSettings.get("fkid");
  65.             if(classname && fkid){
  66.                 return "/docs/index/classname:" + classname + "/fkid:" + fkid + ".json";
  67.             }
  68.         },
  69.        
  70.         parse: function(response) {
  71.             data = [];
  72.             _.each(response.models, function(obj){
  73.                 data.push(obj.Doc);
  74.             });
  75.             return data;
  76.         }
  77.    
  78.     });
  79.    
  80.    
  81.     window.UploadView = Backbone.View.extend({
  82.          template: _.template($("#docsAdd").html()),
  83.          
  84.          events: {
  85.             "click #fm-start-upload": "uploadFiles"
  86.          },
  87.          
  88.          initialize: function() {
  89.             _.bindAll(this, "render");
  90.          },
  91.          
  92.          render: function() {
  93.             $(this.el).html(this.template());
  94.            
  95.             return this;
  96.          },
  97.          
  98.          initUploader: function() {
  99.             var self = this;
  100.             this.uploader = new plupload.Uploader({
  101.                 runtimes : "gears, html5, flash, silverlight, browserplus",
  102.                 container: 'fm-upload-table-container',
  103.                 browse_button : "fm-add-files",
  104.                 drop_element : "fm-upload-dropper",
  105.                 url : '/admin/docs/async_upload',
  106.                 flash_swf_url : '/js/plupload/plupload.flash.swf',
  107.                 silverlight_xap_url : '/js/plupload/plupload.silverlight.xap',
  108.                 filters : [
  109.                     {title : "Image files", extensions : "jpg,gif,png"},
  110.                     {title : "Zip files", extensions : "zip"}
  111.                 ]
  112.             });
  113.            
  114.             this.uploader.bind('Init', function(up, params){
  115.                 $("#fm-upload-container").prepend("<h1>" + params.runtime + "</h1>");
  116.             });
  117.            
  118.             this.uploader.init();
  119.            
  120.             this.uploader.bind('FilesAdded', function(up, files){
  121.                 $.each(files, function(i, file){
  122.                     tdName = document.createElement("td");
  123.                         tdName.innerHTML = file.name;
  124.                     tdStatus = document.createElement("td");
  125.                         tdStatus.className = "plupload_file_status";
  126.                         tdStatus.innerHTML = "0%";
  127.                     tdSize = document.createElement("td");
  128.                         tdSize.className = "plupload_file_size";
  129.                         tdSize.innerHTML = plupload.formatSize(file.size);
  130.                     tdDelete = document.createElement("td");
  131.                         tdDelete.innerHTML = "X";
  132.                         tdDelete.className = "plupload_delete"
  133.                     tr = document.createElement("tr");
  134.                         tr.id = file.id;
  135.                         tr.appendChild(tdName); tr.appendChild(tdStatus); tr.appendChild(tdSize); tr.appendChild(tdDelete);
  136.                     $("#fm-upload-table tbody").append(tr);
  137.                     //Delete Function
  138.                     $("#" + file.id + " td.plupload_delete").click(function(e){
  139.                         e.preventDefault();
  140.                         self.uploader.removeFile(self.uploader.getFile(file.id));
  141.                         $("#" + file.id).remove();
  142.                         return false;
  143.                     });
  144.  
  145.                 });
  146.             });
  147.            
  148.             this.uploader.bind('UploadProgress', function(up, file){
  149.                 $("#" + file.id + " .plupload_file_status").html(file.percent + "%");
  150.            
  151.             });
  152.            
  153.             this.uploader.bind('FileUploaded', function(up, file){
  154.                
  155.                 files = self.uploader.files;
  156.                 lastfile = files[files.length-1];
  157.                
  158.                
  159.                 model = new Doc({
  160.                     filename: file.name,
  161.                     classname: appSettings.get("classname"),
  162.                     fkid: appSettings.get("fkid")
  163.                 });
  164.                 model.save(model.attributes, {
  165.                     success: function(model, response){
  166.                         if(model.get("classname") && model.get("fkid")){
  167.                             app.galleryCollection.add(model);
  168.                         }
  169.                         if(app.libraryCollection){
  170.                             app.libraryCollection.add(model);
  171.                         }
  172.                         if(lastfile.id == file.id && self.uploader.state == 1){
  173.                             app.navigate("", {trigger: true, replace: true});
  174.                         }
  175.                     }
  176.                 });
  177.             });
  178.            
  179.  
  180.             //The plupload HTML5 code gives a negative z-index making add files button unclickable
  181.             $(".plupload.html5").css({zIndex: 0});
  182.             $("#fm-add-files").css({zIndex: 2});
  183.            
  184.             return this;
  185.          },
  186.          
  187.          uploadFiles: function(e){
  188.             e.preventDefault();
  189.             this.uploader.start();
  190.             return false;
  191.          }
  192.    
  193.     });
  194.    
  195.     window.NavView = Backbone.View.extend({
  196.         el: $("#fm-nav"),
  197.        
  198.         initialize: function(){
  199.             if(appSettings.get("classname")){
  200.                 $("#fm-gallery-link").show();
  201.             }
  202.         },
  203.        
  204.         events: {
  205.             "click #fm-upload-link":    "loadUploader",
  206.             "click #fm-gallery-link":   "loadGallery",
  207.             "click #fm-library-link": "loadLibrary"
  208.         },
  209.        
  210.         loadUploader: function(e){
  211.             e.preventDefault();
  212.             $("#fm-nav a").removeClass("solum-button-primary");
  213.             $("#fm-upload-link").addClass("solum-button-primary");
  214.             app.navigate("add", {trigger: true, replace: true});
  215.         },
  216.        
  217.         loadGallery: function(){
  218.             $("#fm-nav a").removeClass("solum-button-primary");
  219.             $("#fm-gallery-link").addClass("solum-button-primary");
  220.             app.navigate("", {trigger: true, replace: true});
  221.         },
  222.        
  223.         loadLibrary: function(){
  224.             $("#fm-nav a").removeClass("solum-button-primary");
  225.             $("#fm-library-link").addClass("solum-button-primary");
  226.             app.navigate("library", {trigger: true, replace: true});
  227.         }
  228.     });
  229.    
  230.     window.ListView = Backbone.View.extend({
  231.         tagName: "ul",
  232.         id: "docs-list",
  233.        
  234.         initialize: function(){
  235.             _.bindAll(this, "render");
  236.             this.collection.bind("reset", this.render);
  237.         },
  238.        
  239.         render: function(){
  240.             var self = this;
  241.             this.collection.each(function(doc){
  242.                 item = new ListItemView({model: doc});
  243.                 $(self.el).append(item.render().el);
  244.             });
  245.             return this;
  246.         }
  247.    
  248.     });
  249.    
  250.     window.ListItemView = Backbone.View.extend({
  251.         tagName: "li",
  252.         template: _.template($("#docs-list-item").html()),
  253.         events: {
  254.             "click .toggle" :           "toggleEditor",
  255.             "click .fm-delete-link":    "deleteModel"
  256.         },
  257.        
  258.         initialize: function(){
  259.             _.bindAll(this, "render");
  260.             this.model.bind("change", this.render);
  261.             this.render();
  262.         },
  263.        
  264.         render: function(){
  265.             $(this.el).html(this.template(this.model.toJSON()));
  266.             return this;
  267.         },
  268.        
  269.         toggleEditor: function(){
  270.             $editor = $(this.el).find(".fm-list-item-editor");
  271.             view = new EditorView({model: this.model});
  272.             $editor.html(view.render().el);
  273.             $(this.el).find(".fm-list-item-editor").slideToggle();
  274.         },
  275.        
  276.         deleteModel: function(){
  277.             self = this;
  278.             if(confirm("Are you sure")){
  279.                 self.model.destroy({
  280.                     success: function(model, response){
  281.                         if(response.success){
  282.                             $(self.el).remove();
  283.                         }
  284.                     }
  285.                 });
  286.             }
  287.         }
  288.        
  289.     });
  290.    
  291.     window.EditorView = Backbone.View.extend({
  292.         template: _.template($("#fm-editor").html()),
  293.         events: {
  294.             "click .fm-save-button" :   "saveModel"
  295.         },
  296.        
  297.         initialize: function(){
  298.             _.bindAll(this, "render");
  299.             this.render();
  300.         },
  301.        
  302.         render: function(){
  303.             $(this.el).html(this.template(this.model.toJSON()));
  304.             $(this.el).find('.fm-details-link').addClass("active-link");
  305.             return this;
  306.         },
  307.        
  308.         saveModel: function(){
  309.             self = this;
  310.             form = $(this.el).find("form").serializeArray();
  311.             _.each(form, function(field){
  312.                 self.model.set(field["name"], field["value"]);
  313.             });
  314.             self.model.save();
  315.             aggregator.trigger("fileUpdated", this.model);
  316.         }
  317.     });
  318.    
  319.     var AppRouter = Backbone.Router.extend({
  320.         routes: {
  321.             "":             "gallery",
  322.             "add":          "add",
  323.             "edit/:id":     "edit",
  324.             "library":      "library"
  325.         },
  326.         initialize: function() {
  327.            
  328.             new NavView();         
  329.             this.galleryCollection = new GalleryCollection();
  330.             this.galleryCollection.fetch();
  331.            
  332.             _.bindAll(this, "index");
  333.             this.bind("all", function(){
  334.                 if(window.ias) window.ias.cancelSelection();
  335.             });
  336.         },
  337.        
  338.         index: function(){
  339.        
  340.         },
  341.        
  342.         library: function() {
  343.             if(!this.libraryCollection){
  344.                 this.libraryCollection = new LibraryCollection();
  345.                 this.libraryCollection.fetch();
  346.             }
  347.             $("#fm-nav a").removeClass("solum-button-primary");
  348.             $("#fm-library-link").addClass("solum-button-primary");
  349.             $("#fm-content").empty();
  350.             view = new ListView({collection: this.libraryCollection});
  351.             $("#fm-content").append(view.render().el);
  352.         },
  353.        
  354.         gallery: function(){
  355.             $("#fm-nav a").removeClass("solum-button-primary");
  356.             $("#fm-gallery-link").addClass("solum-button-primary");
  357.             $("#fm-content").empty();
  358.             view = new ListView({collection: this.galleryCollection});
  359.             $("#fm-content").append(view.render().el);
  360.         },
  361.        
  362.         add: function(){
  363.             $("#fm-nav a").removeClass("solum-button-primary");
  364.             $("#fm-upload-link").addClass("solum-button-primary");
  365.             $("#fm-content").empty();
  366.             view = new UploadView();
  367.             $("#fm-content").append(view.render().el);
  368.             view.initUploader();
  369.         },
  370.        
  371.         edit: function(id) {
  372.             $("#fm-content").empty();
  373.             view = new DocEditView({model: this.docs.get(id)});
  374.             $("#fm-content").html(view.render().el);
  375.         }
  376.     });
  377.    
  378.     var appSettings = new Settings();
  379.     var app = new AppRouter();
  380.     Backbone.history.start();
  381.    
  382. })(jQuery);