var Backbone = require('backbone');
var fs = require('fs');
var path = require('path');
var _ = require('underscore');
var XRegExp = require('xregexp').XRegExp;
var moment = require('moment');
var request = require('request');

exports.Updater = Backbone.Model.extend({

    defaults: {
        lastUpdate: null,
        config: null
    },

    initialize: function() {},

    update: function() {
        var config = this.get('config');
        if (!fs.existsSync(config.outputBase)) {
            fs.mkdirSync(config.outputBase);
        }

        // Load the root content XML file.
        request(config.rootXml, _.bind(this._processRootXml, this));
    },

    _processRootXml: function(error, response, body) {
        var config = this.get('config');
        fs.writeFile(config.outputBase + 'content.xml', body);

        // Collect any URLs in root file.
        var pattern = new XRegExp(/>(http.*?)</gi);
        var matches = [];
        var match;

        while (true) {
            match = pattern.exec(body);
            if (!match) {
                break;
            }
            matches.push(match);
        }

        pattern = new XRegExp(config.cmsRoot + '/(.*)');
        _.each(matches, function(element, index, list) {
            var url = element[1];
            var filepath = config.outputBase + XRegExp.exec(url, pattern)[1];

            if (!fs.existsSync(filepath)) {
                // The file doesn't exist locally, so download it.
                this._downloadLinkedFile(url, filepath);
            } else {
                // The file does exist locally, check if the remote one is newer.
                var localFileModified = moment(fs.statSync(filepath).mtime);
                request({
                    url: url,
                    method: 'HEAD'
                }, _.bind(function(error, response, body) {
                    var remoteFileModified = moment(response.headers['last-modified']);
                    if (remoteFileModified.isAfter(localFileModified)) {
                        this._downloadLinkedFile(url, filepath);
                    } else {
                        console.log('Skipping ' + url);
                    }
                }, this));
            }
        }, this);
    },

    // Download a file to a given path on disk.
    _downloadLinkedFile: function(url, filepath) {
        console.log('Downloading ' + url);

        var dir = path.dirname(filepath);
        if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir);
        }

        request(url, function(error, response, body) {
            if (error) {
                console.log('Error loading ' + url);
                console.log(error);
            }
        }).pipe(fs.createWriteStream(filepath));
    }
});

@@ -326,16 +326,116 @@
 ig: null
+,%0A        filesToLoad: 0,%0A        filesLoaded: 0,%0A        fileLoading: null,%0A        fileProgress: 0
 %0A    %7D,%0A
@@ -533,24 +533,25 @@
 nfig');%0A
+%0A
         
 if (!fs.
@@ -534,37 +534,82 @@
 fig');%0A%0A        
-if (!
+// Create the target directory if needed.%0A        
 fs.existsSync(co
@@ -601,20 +601,16 @@
 s.exists
-Sync
 (config.
@@ -619,17 +619,67 @@
 tputBase
-)
+, _.bind(function(exists) %7B%0A            if (!exists
 ) %7B%0A    
@@ -682,32 +682,36 @@
             
+    
 fs.mkdir
 Sync(config.
@@ -698,20 +698,16 @@
 fs.mkdir
-Sync
 (config.
@@ -716,18 +716,48 @@
 tputBase
-);
+, 0777, _.bind(function(error) %7B
 %0A       
@@ -757,27 +757,24 @@
         
-%7D%0A%0A
         
 // Load 
@@ -769,43 +769,168 @@
     
-// Load the root content XML file.%0A
+    console.log(this);%0A                    request(config.rootXml, _.bind(this._processRootXml, this));%0A                %7D, this));%0A            %7D else %7B%0A        
     
@@ -990,24 +990,57 @@
 ml, this));%0A
+            %7D%0A        %7D, this));%0A
     %7D,%0A%0A    
@@ -1736,37 +1736,32 @@
 %5D;%0A%0A            
-if (!
 fs.existsSync(fi
@@ -1753,20 +1753,16 @@
 s.exists
-Sync
 (filepat
@@ -1762,21 +1762,79 @@
 filepath
-)) %7B%0A
+, _.bind(function(exists) %7B%0A                if (!exists) %7B%0A    
         
@@ -1900,32 +1900,36 @@
                 
+    
 this._downloadLi
@@ -1957,32 +1957,36 @@
 h);%0A            
+    
 %7D else %7B%0A       
@@ -1970,32 +1970,36 @@
        %7D else %7B%0A
+    
                 
@@ -2064,16 +2064,94 @@
  newer.%0A
+                    fs.stat(filepath, _.bind(function(error, stats) %7B%0A        
         
@@ -2193,29 +2193,13 @@
 ent(
-fs.
 stat
-Sync(filepath)
+s
 .mti
@@ -2203,16 +2203,24 @@
 mtime);%0A
+        
         
@@ -2257,16 +2257,24 @@
         
+        
 url: url
@@ -2295,16 +2295,24 @@
         
+        
 method: 
@@ -2318,16 +2318,24 @@
  'HEAD'%0A
+        
         
@@ -2402,24 +2402,32 @@
             
+        
 var remoteFi
@@ -2498,24 +2498,32 @@
             
+        
 if (remoteFi
@@ -2579,32 +2579,40 @@
                 
+        
 this._downloadLi
@@ -2648,32 +2648,40 @@
                 
+        
 %7D else %7B%0A       
@@ -2665,32 +2665,40 @@
        %7D else %7B%0A
+        
                 
@@ -2749,34 +2749,44 @@
                 
-%7D%0A
+        %7D%0A  
                 
@@ -2777,32 +2777,38 @@
                 
+      
 %7D, this));%0A     
@@ -2806,33 +2806,85 @@
 ));%0A            
-%7D
+        %7D));%0A                %7D%0A            %7D, this));
 %0A        %7D, this

remove sync methods