(function($){

  var CATEGORY_TYPES ="adaptation & restoration|buildings for the arts|places of learning|residential|landscapes|installations|furniture|exhibit design|masterplanning|sustainable design|urban design|workplace design|hotels|restaurants|mixed-use|high-rise|housing".split('|')

  Categories = function(viewElement, catsOrder){
    var dom = $(viewElement)
    var categories = catsOrder
    
    var that = {
      state:'collapsed',
      filter:'All',
      init:function(){
        dom.find('>.selector')
          .html(that.filter)
          .mouseenter(that.expand)
        
        var catLinks = ""
        $.each(categories, function(i, cat){
          catLinks += "<a href='#'>"+capcase(cat)+"</a>"
        })
        dom.find('>.popup')
          .html(catLinks)
          .mouseleave(that.collapse)
          .find('a').live('click', that.choose)
        return that
      },
      choose:function(e){
        var newChoice = e.target.text.toLowerCase()
        
        var cats = []
        if (newChoice!="all") cats.push('all')
        cats = cats.concat($.map(categories, function(cat){
          if (cat!=newChoice) return cat
        }))
        var catLinks = ""
        $.each(cats, function(i, cat){
          catLinks += "<a href='#'>"+capcase(cat)+"</a>"
        })
        dom.find('>.popup')
          .html(catLinks)
        dom.find('>.selector')
          .html(capcase(newChoice))
        that.collapse()
        
        that.filter = newChoice
        
        dom.trigger({
          type:"filter",
          filter:newChoice.toLowerCase()
        })
        
        return false
      },
      select:function(newFilter){
        if (newFilter=='all' || $.inArray(newFilter, categories)>-1){
          that.choose({target:{text:newFilter}})
        }
      },
      expand:function(e){
        if (that.state=='expanded') return
        that.state = 'expanded'
        dom.find('>.popup').show().hoverFlow(e.type, { opacity: 1 }, 'fast');
        dom.find('>.status').addClass('expanded')
        
      },
      collapse:function(e){
        if (that.state=='collapsed') return
        if (e && $(e.toElement).hasClass('selector')) return
        that.state = 'collapsed'
        dom.find('>.popup').hoverFlow("mouseleave", { opacity: 0 }, 'fast', function(){
         $(this).hide()
        });
        dom.find('>.status').removeClass('expanded')
      },
      omissions:function(catsInUse){
        var newCats = []
        $.each(categories, function(i,cat){
          if (catsInUse[cat]) newCats.push(cat)
        })
        categories = newCats

        catLinks = ""
        var cur = that.filter.toLowerCase()
        if (cur!='all') catLinks = "<a href='#'>All</a>"
        $.each(categories, function(i, cat){
          if (cat==cur) return
          catLinks += "<a href='#'>"+capcase(cat)+"</a>"
        })
        dom.find('>.popup').html(catLinks)
      }
      
    }
    
    return that.init()
  }
  

  var Stills = function(elt, projects){
    var dom = $(elt)
    var that = {
      images:{},
      active:null,
      init:function(){
        var bg = new Image()
        bg.src = '/img/off-white.png'

        var imgs = ""
        $.each(projects, function(pid, proj){
          if (proj.poster.length==0) return
          imgs += "<img class='"+pid+"' src='/db/awa/"+pid+"/"+proj.poster+"'>"
        })
        dom.append(imgs)
        
        dom.find("img").hide()
        dom.css('opacity',0)

        $(window).resize(that.resize)
        that.resize()
        return that
      },
      peek:function(proj_id){
        var showing = dom.find("img.active")
        if (showing.length>0){
          dom.stop(true).animate({opacity:0},200,function(){
            dom.find("img.active").hide().removeClass('active')
            dom.find('img.'+proj_id).show().addClass('active')
          })
          .animate({opacity:1},500)
        }else{
          dom.find('img.'+proj_id).show().addClass('active')
          dom.stop(true).animate({opacity:1},500)
        }
      },
      leave:function(){
        dom.stop(true).animate({opacity:0},500)
      },

      resize:function(){
        var win = {width:$(window).width(), height:$(window).height()}
        var mag = Math.max(win.width/960, win.height/540)
        var dims = {width:960*mag, height:540*mag}
        var offset = {left:(win.width-dims.width)/2, top:(win.height-dims.height)/2}
        dom.css({width:dims.width, height:dims.height, 
                 left:offset.left, top:offset.top})
      },
    }
    
    return that.init()    
  }
  

  var Vignette = function(elt, rows){
    elt = $(elt).get(0)

    var that = {
      dom:null,
      swf:null,
      suspended:false,
      projects:{},
      current:null,
      initPeek:null,
      peekTimer:null,
      stills:null,
      init:function(){
        $.each(rows, function(i, row){
          that.projects[row.id] = row.value
        })
        
        // load the swf and set up a global fn for externalinterface to call
        AWAInitCallback = that.connect
        AWAPeekOverCallback = that.left
        var params = {
          scale:"noscale",
          salign:'lt',
          bgcolor:"#FFFFFF",
          wmode:'opaque',
          allowScriptAccess:"sameDomain"
        }
        var attributes = {id:'vignette'}
        var flashvars = {}
        swfobject.embedSWF("/lib/vignette.swf", "vignette-shell", "100%", "100%", "9.0.0","", flashvars, params, attributes);


        that.stills = Stills("#stills", objcopy(that.projects))
        $(that.stills).bind('left',that.left)
        $("#projects a.name").hover(that.peek, that.maybeUnpeek)

        // trigger the swf to show/hide the posters on mouseover
        $("#projects a.pullquote").hover(that.peek, that.maybeUnpeek)
        $("#projects a.pullquote").click(that.enter)
        
        $("#vignette-overlay .logo").click(that.leave)
        $("#vignette-overlay #escape").click(that.leave)
        that.peekTimer = Timer(200,1)
        $(that.peekTimer).bind('timer',that.reallyUnpeek)
        return that
      },
      
      peek:function(e){
        if (that.suspended) return
        if($(e.target).css('opacity')<.5) return
        
        $(that).trigger({type:'peek'})
        
        var hovered = $(e.target)
        if (hovered.hasClass('pullquote')){
          var project_id = e.target.href.replace(/^.*?#\//,"")  
          hovered.addClass('highlighted').prev('a').addClass('highlighted')
          var has_video = true
        }else{
          project_id = e.target.href.replace(/^.*projects\//,"")
          hovered.addClass('highlighted')
          has_video = false//hovered.parent().hasClass('quoted')
        }
        
        if (that.peekTimer.running){
          that.peekTimer.stop()
          if (project_id==that.current.id && has_video==that.current.video) return
          that.reallyUnpeek()
        }
        
        if (has_video){
          if (that.swf) that.swf.peek(project_id, has_video)
          else that.initPeek = project_id
        }else{
          that.stills.peek(project_id)
        }
        
        that.current = {id:project_id, video:has_video}
        $("#static-content").css('background','transparent')
        $("#static-content .categories").css('background','transparent')
      },
      maybeUnpeek:function(e){
        if (that.suspended) return 
        $(e.target).removeClass("highlighted")
        $("a.highlighted").removeClass("highlighted")
        that.peekTimer.start()
      },
      reallyUnpeek:function(e){
        if (that.swf) that.swf.leave() 
        else that.initPeek = null
        that.stills.leave()
      },      
      enter:function(e){
        if (that.suspended) return false
        that.suspended = true
        var project_id = e.target.href.replace(/^.*?#\//,"")
        if (that.swf) that.swf.enter(project_id)
        $("#static-content").fadeOut('slow')
        $("#vignette-overlay").fadeIn('slow')
        $("#vignette-overlay a.project-link").attr('href','/projects/'+project_id)
                                             .text(that.projects[project_id].name)
        // // $(e.target).removeClass("highlighted")
        $("a.highlighted").removeClass("highlighted")
        // $('body').css('overflow','hidden') // <- this bombs in ff. why?
        that.current = {id:project_id, video:true}
        return false
      },
      leave:function(e){
        if (that.swf) that.swf.leave()
        that.suspended = false
        $('body').css('overflow','inherit')
        $("#static-content").fadeIn('slow')
        $("#vignette-overlay").fadeOut('slow')
        $("#vignette-overlay a.project-link").empty()
        return false
      },
      left:function(e){
        // $("#static-content").css('background','white')
        // $("#static-content .categories").css('background','white')
      },
      connect:function(e){
        that.dom = $("#vignette")
        that.swf = that.dom.get(0)
        return {peek:that.initPeek, projects:that.projects}
        that.initPeek = null
      },
      
    }
    
    return that.init()    
  }
  


  MCP = function(){
    var host = window.location.host
    window.STATIC_DB = !(host.match(/^preview/) || host.match(/localhost/))
    
    var db = $.couch.db('awa')
    var that = {
      // BUG: end this capcase nonsense. why why why...
      fixedCategories:CATEGORY_TYPES,
      indices:null,
      currentFilter:'all',
      vignette:null,
      categories:null,
      furled:true,
      init:function(){

        // listen to filter menu to decide which elements to show/hide
        that.categories = Categories('.categories', that.fixedCategories)
        $('.categories').bind('filter', that.filter)

        // the vignettes swf needs jpg/f4v paths + some project info
        db.view('projects/all', {success:function(resp){
          that.vignette = Vignette("#vignette-shell", resp.rows)
          $(that.vignette).bind('peek',function(e){that.categories.collapse(e)})
        }})

        // cache the real string values so the filter animation can
        // chop up the text willy nilly
        $('#projects a').each(function(i, elt){
          $$(elt).fulltext = $(elt).html()
        })
        
        $("a.logo").click(function(e){
          that.categories.select('all')
          return false
        })

        $.address.change(that.navigate)   

        // we need the category indices for handling filter events
        db.list('projects/grouped','bytype', {success:function(categories){
          that.indices = categories
          
          var newFilter = $.address.pathNames()[0] || ""
          newFilter = newFilter.replace(/_/g,' ')

          that.categories.omissions(categories)

          if ($.inArray(newFilter, that.fixedCategories)>-1){
            that._markHiding(newFilter)
            that.unfurl(0)
          }
        }})

        return that  
      },

      unfurl:function(dt){
        if (!that.furled) return
        that.furled = false
        var incr = (dt!==0)
        // fade-in the projects links in a wave
        // (should skip this when it's a back button move or a category link)
        var cats_dt = 0
        var any_hidden = false
        $("#projects .name,.quoted > .pullquote").each(function(i,elt){
          if ($$(elt).hiding){
            $(elt).fadeTo(0,0).css('visibility','visible').hide()
            any_hidden = true
          }else{
            $(elt).fadeTo(0,1).css('visibility','visible')
          }
        })
        if (any_hidden){
          var fade_bits = ".depts>a,#cc"
        }else{
          fade_bits = ".depts>a,.pullquote,#projects>a,#cc"
          $("#projects .name,.quoted > .pullquote").fadeTo(0,0)
        }
        
        $(fade_bits).fadeTo(0,0).css('visibility','visible')
          .each(function(i,elt){
            if (elt.tagName=='A' && $$(elt).hiding){
              return
            }
            $(elt).delay(dt).fadeTo('slow',1)
            if ($(elt).hasClass('pullquote')){
              // the vignettes with pullquotes
              $(elt).prev('a').delay(dt).fadeTo('slow',1)
              if (incr) dt+=200
            }else if ($(elt).hasClass('name')){
              // the non-vignette projects
              if (cats_dt===0) cats_dt = dt
              if (incr) dt+=90
            }else{
              // the depts links in the nav
              if (incr) dt+=220
            }
          })

        // the filter needs to load last so no refiltering happens before the anim is complete
        $('.categories').fadeTo(0,0).css('visibility','visible').delay(/*cats_*/dt).fadeTo('slow',1)
      },

      navigate:function(e){
        var newFilter = e.pathNames[0] || "all" // BUG: should this be "all"?
        newFilter = newFilter.replace(/_/g,' ')
        
        if ($.inArray(newFilter, that.fixedCategories)==-1){
          // for a plain url, animate the projects unless we're coming back
          // from a project page
          var lastpath = readCookie('last') || ""
          var dt = (lastpath.match(/^\/(projects|offices|news|about)/)) ? 0 : 666
          that.unfurl(dt)
        }else{
          // with a filter specified in the hash url, skip the animation
          that.categories.select(newFilter)
          that.currentFilter = newFilter
          // that.unfurl(0)
        }
        createCookie('last','/',1)
      },

      _markHiding:function(newFilter){
        if (newFilter=='') newFilter = 'all'
        
        if (newFilter=='all'){
          $('#projects a').each(function(i, elt){
            $$(elt).hiding = false
          })
        }else{
          $('#projects a').each(function(i, elt){
            $$(elt).hiding = true
          })

          $.each(that.indices[newFilter], function(i, id){
            $('#projects a[href$='+id+']').each(function(i,elt){
              $$(elt).hiding = false
            })
          })
        }
      },
                       
      filter:function(e){        
        if (!that.indices) return
        
        if (that.currentFilter == e.filter) return
        that.currentFilter = e.filter
        
        var rewriteText = function(pct){
          var fullText = $$(this).fulltext
          var newLength = Math.floor(fullText.length * pct)
          var oldLength = $(this).html().length
          if (newLength!=oldLength)
            $(this).html(fullText.substr(0,newLength))
        }
        var clearText = function(){
          $(this).html("").hide()
        }
        
        that.vignette.suspended = true
        
        // flag the project <a>s that should be visibile/hidden in the new filter
        that._markHiding(e.filter)
        
        // animate hide/reveal of text based on .hidden flag
        $("#projects a").each(function(i, elt){
          if ($$(elt).hiding){
            $(elt).stop(true).animate({opacity:0},{duration:1000, easing:'easeInOutSine',
                                        step:rewriteText, complete:clearText})
          }else{
            $(elt).stop(true).show().animate({opacity:1},{duration:1000, easing:'easeInOutSine', 
                                               step:rewriteText})
          }
        })
        setTimeout(function(){that.vignette.suspended = false},1100)

      }
      
    }
    
    return that.init()
  }
  
  
  
})(jQuery)
