// = Apple.com Tutorial Swap View Delegate =
// == AC.Tutorials ==
// Delegate objects for {{{AC.ViewMaster}}} that handles all the basics of a
// standard tutorials browser, including tabs, related galleries, and a
// featured navigation.
if (typeof AC === "undefined") {
    AC = {};
}
if (typeof tracker === "undefined") {
    tracker = false;
}
AC.Tutorials = {};

// === AC.Tutorials.cookie ===
// Object that handles the cookie which stores tutorials you have viewed previously.
AC.Tutorials.cookie = {
    data: [],
    name: 'tutorials',

    // ==== {{{AC.Tutorials.cookie.path()}}} ====
    // Determines the path in which we are currently viewing the tutorials.
    path: function() {
        if (!this._path) {
            this._path = document.location.toString();
            this._path = this._path.replace(/http:\/\/[^\/]*/, '');
            this._path = this._path.replace(/\?.*/, '');
            this._path = this._path.replace(/#.*/, '');
        }
        return this._path;
    },

    // ==== {{{AC.Tutorials.cookie.reset()}}} ====
    // Resets the cookie data to be a unique array.
    reset: function() {
        this.data = this.data.sort().uniq();
    },

    // ==== {{{AC.Tutorials.cookie.read()}}} ====
    // Reads the desired cookie and stores it to an internal array. Returns
    // the array.
    read: function() {
        if (this.data.length == 0) {
            // get the desired cookie and populate the internal data with it
            var cookies = document.cookie.split(';');
            cookies.each(function(cookie) {
                var cookie = cookie.toQueryParams();
                if (cookie[this.name]) {
                    var seen = cookie[this.name].split(',');
                    this.data = this.data.concat(seen);
                    this.reset();
                }
            }.bind(this));
        }

        return this.data;
    },

    // ==== {{{AC.Tutorials.cookie.set(id)}}} ====
    // Appends {{{id}}} to the current cookie. The cookie expires in one week.
    // * {{{id}}} [**string**]: id of the tutorial to add to the cookie.
    set: function(id) {
        // set cookie to expire in 1 week
        var date = new Date();
        date.setDate(date.getDate()+7);
        date.toGMTString();

        // update the internal array
        this.data.push(id);
        this.reset();

        // figure out the cookie data string
        var string = this.data.join(',');
        if (!string.match(id)) {
            string = (string != '') ? string+','+id : id;
        }

        // set the cookie
        document.cookie = this.name+'='+string+'; expires='+date+'; path='+this.path()+'; domain=apple.com';
    }
};


// === AC.Tutorials.TabBrowser ===
// The delegate class the tabs {{{AC.ViewMaster.Viewer}}}. This is what we would intialize on for tutorial browsers with a tabbed view. In which case, this handles the creation of the {{{AC.Tutorials.TutorialBrowser}}} object.
AC.Tutorials.TabBrowser = Class.create({
    tutorialsViewMaster: null,
    tutorialsView: null,
    tutorialsTriggerClassName: null,

    // ==== {{{AC.Tutorials.TabBrowser.initialize(view, triggerClassName, tutorialsView, tutorialsTriggerClassName, options)}}} ====
    // This is the function to call on DOM ready. It sets up the view master, initializes deep linking from the hash, and adds the visited links to any triggers on the page. In addition, this sets up for the intialization of the tutorials view master.
    // * {{{view}}} [**string** or **element**]: the view id or object with which to initialize {{{AC.ViewMaster.Viewer}}}
    // * {{{triggerClassName}}} [**string**]: the triggerClassName with which to initialize {{{AC.ViewMaster.Viewer}}}
    // * {{{tutorialsView}}} [**string** or **element**]: the view id or object with which to initialize {{{AC.Tutorials.TutorialsViewer}}}
    // * {{{tutorialsTriggerClassName}}} [**string**]: the triggerClassName with which to initialize {{{AC.Tutorials.TutorialsViewer}}}
    // * {{{options}}} [**object**]: options that are passed as the {{{AC.ViewMaster.Viewer}}} options
    initialize: function(view, triggerClassName, tutorialsView, tutorialsTriggerClassName, options) {
        this.view = view;
        this.triggerClassName = triggerClassName;
        this.tutorialsView = tutorialsView;
        this.tutorialsTriggerClassName = tutorialsTriggerClassName;
        this.options = options || {};

        AC.Tutorials.cookie.read();

        var tabs = new AC.ViewMaster.Viewer(null, this.view, this.triggerClassName, this.options);
        this.tabs = tabs;
        this.tabs.setDelegate(this);

        if (!this.url) {
            this.url = document.location.toString().replace(document.location.hash, '');
        }
        this.initializeFromHash();

        if (!tracker && AC.ViewMaster.Tracker) {
            tracker = new AC.ViewMaster.Tracker();
            tracker.setDelegate(this);
        }
    },

    // ==== {{{AC.Tutorials.TabBrowser.initializeFromHash()}}} ====
    // This figures out what to do with the hash and how to use it (i.e. show a tab).
    initializeFromHash: function() {
        var initialId = document.location.hash.toString().replace('#', '');

        // preserve old ids (tab=*&tutorial=*)
        if (initialId !='') {
            var newHash = '#'+initialId;
            var query = initialId.toQueryParams();

            if (query.tab && query.tutorial) {
                newHash = '#'+query.tab +'-'+query.tutorial;
            }
            newHash = newHash.replace('-mov-', '-');
            newHash = newHash.replace('-text-', '-');

            document.location = newHash;
        }
        var initialId = document.location.hash.toString().replace('#', '');

        // show the correct initial section for the swap views
        var tab = (!initialId.match('-')) ? initialId : initialId.split('-')[0];

        if (tab && this.tabs.sectionWithId(tab)) {
            this.tabs.show(this.tabs.sectionWithId(tab));
        } else {
            this.tabs.addSection($$('a.'+this.triggerClassName)[0]);
            this.tabs.show(this.tabs.sectionWithId(this.tabs.orderedSections[0]));
        }
    },

    // ==== {{{AC.Tutorials.TabBrowser.didAppendContent(view, content)}}} ====
    // Delegate method for {{{AC.ViewMaster}}}. This creates the {{{AC.Tutorials.TutorialBrowser}}} if we don't already have it. The first time a section is shown, it adds the visited class to the links within the section’s content.
    // * {{{view}}} [**object**]: the {{{AC.ViewMaster}}} object
    // * {{{content}}} [**element**]: the HTML element for the content we just appended
    didAppendContent: function(view, content) {
        var section = view.currentSection;
        if (section && !this.tutorialsViewMaster) {
            this.tutorialsViewMaster = new AC.Tutorials.TutorialBrowser(this, this.tutorialsView, this.tutorialsTriggerClassName, this.options);
        }

        if (content && !section.visited) {
            var tutorials = this.tutorialsViewMaster.tutorials;
            AC.Tutorials.cookie.data.each(function(sectionId) {
                content.select('a.'+tutorials.triggerClassName+'[href*='+sectionId+']').each(function(link) {
                    link.addClassName('visited');
                });
            });
            section.visited = true;
        }
    },

    // ==== {{{AC.Tutorials.TabBrowser.didShow(view, outgoing, incoming)}}} ====
    // Delegate method for {{{AC.ViewMaster}}}. Changes the hash to the currently visible section.
    // * {{{view}}} [**object**]: the {{{AC.ViewMaster}}} object
    // * {{{outgoing}}} [**object**]: the outgoing {{{AC.ViewMaster.Section}}} object
    // * {{{incoming}}} [**object**]: the incoming {{{AC.ViewMaster.Section}}} object
    didShow: function(view, outgoing, incoming) {
        // make the address bar reflect the currently viewed section
        if (incoming && this.url && incoming.id != 'clicktoplay') {
            document.location = this.url+'#'+incoming.id;
        }
    },

    // ==== {{{AC.Tutorials.TabBrowser.trackingNameForSection(tracker, name, section)}}} ====
    // Delegate method for {{{AC.ViewMaster.Tracker}}}. This doesn't track tab clicks.
    // * {{{tracker}}} [**object**]: the {{{AC.ViewMaster.Tracker}}} object
    // * {{{name}}} [**string**]: the {{{AC.ViewMaster.Section}}}'s name
    // * {{{section}}} [**object**]: the {{{AC.ViewMaster.Section}}} object
    trackingNameForSection: function(tracker, name, section) {
         if (name.match(/-/)) {
             return name;
         }
         return false;
     }

});

// === AC.Tutorials.TutorialBrowser ===
// The delegate class the tutorials {{{AC.ViewMaster.Viewer}}}. This is what we would intialize on for tutorial browsers without a tabbed view.
AC.Tutorials.TutorialBrowser = Class.create({

    // ==== {{{AC.Tutorials.TutorialBrowser.initialize(view, triggerClassName, options)}}} ====
    // This is the function to call on DOM ready. It sets up the view master, initializes deep linking from the hash, and adds the visited links to any triggers on the page.
    // * {{{view}}} [**string** or **element**]: the view id or object with which to initialize {{{AC.ViewMaster.Viewer}}}
    // * {{{triggerClassName}}} [**string**]: the triggerClassName with which to initialize {{{AC.ViewMaster.Viewer}}}
    // * {{{options}}} [**object**]: currently this has no function:(
    initialize: function(view, triggerClassName, options) {
		//console.log('hi: '+arguments[0]+", "+arguments[1]+", "+arguments[2])
        this.view = view;
        this.triggerClassName = triggerClassName;
        this.options = options || {};

        // offset the arguments if we are initializing from a tab viewer
        if (arguments.length == 4) {
            this.tabDelegate = arguments[0];
            this.view = arguments[1];
            this.triggerClassName = arguments[2];
            this.options = arguments[3];
        }

        AC.Tutorials.cookie.read();

        // initialize the tutorial swap view & set the delegate
        var tutorials = new AC.ViewMaster.Viewer(null, this.view, this.triggerClassName, this.options);
        this.tutorials = tutorials;
        this.tutorials.setDelegate(this);

        this.initializeSplashFrame();

        AC.Tutorials.cookie.data.each(function(sectionId) {
            $$('a.'+tutorials.triggerClassName+'[href*='+sectionId+']').each(function(link) {
                link.addClassName('visited');
            });
        }.bind(this));

        if (!this.url) {
            this.url = document.location.toString().replace(document.location.hash, '');
        }
        this.initializeFromHash();

        if (!tracker && AC.ViewMaster.Tracker) {
            tracker = new AC.ViewMaster.Tracker();
        }
    },

    // ==== {{{AC.Tutorials.TutorialBrowser.initializeSplashFrame()}}} ====
    // This sets up the click to play frame, basically adding a controller that plays the click to play movie and activates the links within.
    initializeSplashFrame: function() {
        // grab the splash
        var splash = $('clicktoplay');
        if (splash) {

            // create a "fake" controller that plays the movie onclick
            var link = splash.down('.'+this.triggerClassName);
            var container = document.createElement('a');
            container.className = 'controllerPanel '+this.triggerClassName;
            container.href = link.href;
			if (typeof (AC.QuickTime) != "undefined" && typeof (AC.QuickTime.Controller) != "undefined") {
            var controller = new AC.QuickTime.Controller();
            container.appendChild(controller.render());
            link.up('div').appendChild(container);
			}
            // we have to "fake" the activation of the links in the featured
            // nav since the current section is actually the 'clicktoplay'
            // section not the section in the href
            var section = link.href.replace(/.*#/, '');
            var otherLinks = splash.select('.'+this.triggerClassName);
            otherLinks.each(function(link) {
                var id = link.href.replace(/.*#/, '');
                if (id.match(section)) {
                    link.addClassName('active');
                }
            });

            // for IE, view master will add it back
            splash.remove();

            // add the section so we can show it later:)
            this.tutorials.addSection(splash);
        }

        return splash;
    },

    // ==== {{{AC.Tutorials.TutorialBrowser.initializeFromHash()}}} ====
    // This figures out what to do with the hash and how to use it (i.e. show a tutorial).
    initializeFromHash: function() {
        // show the correct initial section for the swap views
        var initialId = document.location.hash.toString().replace('#', '');

        // preserve old ids (tutorial=*)
        if (initialId != '') {
            var newHash = '#'+initialId;
            var query = initialId.toQueryParams();

            if (query.tutorial) {
                newHash = '#'+query.tutorial;
            }
            newHash = newHash.replace('-mov-', '-');
            newHash = newHash.replace('-text-', '-');

            document.location = newHash;
        }
        var initialId = document.location.hash.toString().replace('#', '');

        if (initialId != '') {
            var permutations = initialId.split('-');
            var initialId = [];
            for (var i=permutations.length-1; i>=0; i--) {
                for (var j=0; j<initialId.length; j++) {
                    initialId[j] = permutations[i]+'-'+initialId[j];
                }
                initialId.push(permutations[i]);
            }

            for (var i=0; i<initialId.length; i++) {
                var section = $$('a.'+this.tutorials.triggerClassName+'[href$='+initialId[i]+']');
                if (section.length>0) {
                    section = this.tutorials.addSection(section[0]);
                    if (initialId[0].match(/-gallery\d*$/)) {
                        section.showGallery = initialId[0];
                    }
                    this.tutorials.show(section);
                    break;
                }
            }
        }

        if (!this.tutorials.currentSection) {
            this.tutorials.show(this.tutorials.sectionWithId('clicktoplay'));
        }
    },

    // ==== {{{AC.Tutorials.TutorialBrowser.willShow(view, outgoing, incoming)}}} ====
    // If we have an associated gallery image src, this creates the gallery image and appends it to the incoming.content element. This is to ensure we aren’t preloading images that we aren’t going to ever click on.
    // * {{{view}}} [**object**]: the {{{AC.ViewMaster}}} object
    // * {{{outgoing}}} [**object**]: the outgoing {{{AC.ViewMaster.Section}}} object
    // * {{{incoming}}} [**object**]: the incoming {{{AC.ViewMaster.Section}}} object
    willShow: function(view, outgoing, incoming) {
		//console.log(arguments[0]+", "+arguments[1]+", "+arguments[2].imageSrc)
        if (this.tabDelegate) {
            this.tabDelegate.tabs.show(this.tabDelegate.tabs.sectionWithId(incoming.id.split('-')[0]));
        }

        if (incoming.imageSrc && !incoming.image) {
            incoming.image = document.createElement('img');
            incoming.image.className = 'swapimage';
            incoming.image.src = incoming.imageSrc;
            incoming.content.appendChild(incoming.image);
        }
    },

    // ==== {{{AC.Tutorials.TutorialBrowser.getMovieImagePath(view, section, content)}}} ====
    // Gets the movie dimensions from the movie link’s query string, or default.
    // * {{{section}}} [**object**]: the {{{AC.ViewMaster.Section}}} object
    getMovieImagePath: function(section) {
        var movieParams = section.movieLink.getAttribute('href', 2).toQueryParams();
        var width = movieParams.width || 640;
        var height = movieParams.height || 480;
		//FMI adjust
//console.log("TB-line 361) width:"+width+"\n"+"height:"+height)
        return '/site/images/overlays/overlay_movie_endstate_640x360.jpg';
		
		//return 'http://images.apple.com/global/elements/quicktime/qt_endstate'+width+'x'+height+'.jpg';
		///site/images/overlays/overlay_movie_endstate_640x360.jpg
    },

    // ==== {{{AC.Tutorials.TutorialBrowser.createPosterLink(view, section, content)}}} ====
    // If we didn’t include a mobile poster link, this creates a generic mobile poster link for a movie at the current size.
    // * {{{section}}} [**object**]: the {{{AC.ViewMaster.Section}}} object
    createPosterLink: function(section) {
        if (!section.posterLink) {
            section.posterLink = document.createElement('a');
            section.posterLink.className = 'posterLink';
            section.posterLink.href = this.getMovieImagePath(section);
        }
    },

    // ==== {{{AC.Tutorials.TutorialBrowser.createEndState(view, section, content)}}} ====
    // If we didn’t include an end state, this creates a generic endstate with replay link for a movie at the current size.
    // * {{{section}}} [**object**]: the {{{AC.ViewMaster.Section}}} object
    createEndState: function(section) {
        // create the end state and replay button if we're lazy
        if (!section.endState) {
            section.endState = document.createElement('div');
            section.endState.className = 'endState';
            section.endState.innerHTML = '<img src="'+this.getMovieImagePath(section)+'">';

            if (this.options.replayButtonText) {
                var replay = new Element('a', { className:'replay pillbutton', href:'#'+section.id });
                replay.innerHTML = '<span>'+this.options.replayButtonText+'</span><b>&gt;</b>';
                if (replay) {
                    replay.observe('click', function(evt) {
                        evt.stop();
                        this.replayMovie();
                    }.bindAsEventListener(section));
                }
                section.endState.appendChild(replay);
            }
        }
    },

    // ==== {{{AC.Tutorials.TutorialBrowser.setUpGallery(view, outgoing, incoming)}}} ====
    // If we have gallery content, create a nested view master for it.
    // * {{{view}}} [**object**]: the {{{AC.ViewMaster}}} object
    // * {{{section}}} [**object**]: the {{{AC.ViewMaster.Section}}} object
    // * {{{content}}} [**element**]: the HTML element for the content we just appended
    setUpGallery: function(view, section, content) {
//console.log('section.relatedGallerySection: '+section.relatedGallerySection)
//console.log('section.gallery: '+section.gallery)
//console.log('content.down: '+content.down)
        section.relatedGallerySection = content.down('div.gallery');
        if (section.relatedGallerySection && !section.gallery) {
//console.log('if')
            var galleryContainer = document.createElement('div');
            galleryContainer.id = section.id+'Container';
            galleryContainer.className = 'galleryContainer';
            section.relatedGallerySection.appendChild(galleryContainer);

            section.gallery = new AC.ViewMaster.Viewer(null, section.id+'Container', 'gallery-link-'+section.id);
//console.log(this)
            section.gallery.setDelegate(this);




            section.relatedGallerySection.select('.nav a').each(function(link) {
			 // section.relatedGallerySection.select('ol.nav li a').each(function(link) {
                var id = link.href.replace(/.*#/, '');
                var src = link.href.replace(/#.*/, '');

                // add the correct triggerClassName to the link
                link.addClassName('gallery-link-'+section.id);

                // rewrite the href to pretend like we're not remote
                link.href = '#'+id;

                // create a dummy content div
                var wrapper = document.createElement('div');
                wrapper.id = id;
                wrapper.className = 'swapImage';
                section.relatedGallerySection.appendChild(wrapper);

                // add a swap view section
                var gallerySection = section.gallery.addSection(link);
                gallerySection.imageSrc = src;
				
				new Effect.ScrollTo($('content'), {duration: 0.3});
            });
  

            section.gallery.show(section.gallery.sectionWithId(section.gallery.orderedSections[0]));
        }
    },

    // ==== {{{AC.Tutorials.TutorialBrowser.didAppendContent(view, content)}}} ====
    // Delegate method for {{{AC.ViewMaster}}}. Know-it-all function: lazy loads movie elements; activates triggers within the content node; sets up the related gallery; adds the visited class to the triggers and sets the cookie to reflect that.
    // * {{{view}}} [**object**]: the {{{AC.ViewMaster}}} object
    // * {{{content}}} [**element**]: the HTML element for the content we just appended
    didAppendContent: function(view, content) {
        var section = view.currentSection;
//console.log("args: "+arguments[0]+", "+arguments[1])
        if (section) {
//console.log("section: "+section)
            // create the movie elements that we didn’t do by hand
            if (section.movieLink) {
                this.createPosterLink(section);
                this.createEndState(section);
				new Effect.ScrollTo($('content'), {duration: 0.3});
            }

            if (content) {
                this.setUpGallery(view, section, content);
				
            }
            // set the visited class on the triggers
            section.triggers().each(function(trigger) {
                trigger.addClassName('visited');
            });


            // set a cookie to remember we visited this tutorial
            AC.Tutorials.cookie.set(section.id);
			
        }
		
		
		
    },

    // ==== {{{AC.Tutorials.TutorialBrowser.didShow(view, outgoing, incoming)}}} ====
    // Delegate method for {{{AC.ViewMaster}}}. Shows the gallery if we've flagged it for showing. Activates or deactivates the related sections triggers. And changes the hash to the currently visible section.
    // * {{{view}}} [**object**]: the {{{AC.ViewMaster}}} object
    // * {{{outgoing}}} [**object**]: the outgoing {{{AC.ViewMaster.Section}}} object
    // * {{{incoming}}} [**object**]: the incoming {{{AC.ViewMaster.Section}}} object
    didShow: function(view, outgoing, incoming) {
        if (incoming.showGallery) {
            var gallerySection = this.tutorials.addSection(incoming.relatedGallerySection);
            this.tutorials.show(gallerySection);
            if (incoming.gallery.sectionWithId(incoming.showGallery)) {
                incoming.gallery.show(incoming.gallery.sectionWithId(incoming.showGallery));
            } else {
                incoming.gallery.show(incoming.gallery.sectionWithId(incoming.gallery.orderedSections[0]));
            }
            incoming.showGallery = false;
        }

        // add active classes to the incoming's sections related movie triggers
        if (outgoing && outgoing.id == incoming.id.replace(/-gallery\d*$/, '')) {
            outgoing.triggers().each(function(trigger) {
                trigger.addClassName('active');
            });
        }

        // remove active classes to the outgoing's sections related gallery triggers
        if (outgoing && outgoing.id.match(/-gallery\d*$/) && !outgoing.id.match(incoming.id)) {
            var outgoing = this.tutorials.sectionWithId(outgoing.id.replace(/-gallery\d*$/, ''));
            if (outgoing) {
                outgoing.triggers().each(function(trigger) {
                    trigger.removeClassName('active');
                });
            }
        }

        // make the address bar reflect the currently viewed section
        if (incoming && this.url && incoming.id != 'clicktoplay') {
            document.location = this.url+'#'+incoming.id;
        }
    }
});



