
/*<html>
<body>
<script type="text/javascript" >
*/


var _firstLoad = true;

(function() {
    var PREFIX = "zocdoc_";
 
    attachEventListener(window, 'load', Initialize, false);
    

    function attachEventListener(target, eventType, functionRef, capture) {
        if(typeof(functionRef)== 'string') {
            functionRef=eval(functionRef);
        }

        if (typeof target.addEventListener != "undefined"){
            target.addEventListener(eventType, functionRef, capture);
        } else if (typeof target.attachEvent != "undefined"){
            target.attachEvent("on" + eventType, functionRef);
        } else {
            eventType = "on" + eventType;

            if(typeof target[eventType] == "function") {
                var oldListener = target[eventType];
                target[eventType] = function() {
                    oldListener();                    
                    return functionRef();
                };
            }else {
                target[eventType] = functionRef;
            }
        }
    }

    function Initialize() {
        var baseUrl = 'http://offsiteschedule.zocdoc.com';

        var headElm = document.getElementsByTagName('head')[0];

        //stylesheets
        var styleElm = document.createElement('link');
        styleElm.rel = 'stylesheet';
        styleElm.type = 'text/css';
        styleElm.href = baseUrl + '/remote/Schedule.css.aspx?prefix=' + PREFIX;
        
        if(headElm.childNodes.length == 0)
            headElm.appendChild(styleElm);
        else
            headElm.insertBefore(styleElm, headElm.childNodes[0]);

        /*@cc_on
            var ie6StyleElm = document.createElement('link');
            ie6StyleElm.rel = 'stylesheet';
            ie6StyleElm.type = 'text/css';
            ie6StyleElm.href = baseUrl + '/remote/Schedule_ie6.css.aspx?prefix=' + PREFIX;
            
            if(headElm.lastChild == styleElm) {
                headElm.appendChild(ie6StyleElm);
            } else {
                headElm.insertBefore(ie6StyleElm, headElm.childNodes[1]);
            }
        @*/
        
        var anchors = document.getElementsByTagName('a');
        for(var i=0; i<anchors.length; i++) {
            var anchor = anchors[i];
            var href = anchor.href;
            
            href = href.replace(/^\s+|\s+$/g,"");
            href = href.replace(/\/+$/, "");
            href = href.toLowerCase();
            
            if(href.indexOf("http://www.zocdoc.com") > -1 && anchor.rel=="schedule") {
                var schedule = new Schedule(baseUrl, PREFIX, null,1684);
                
                
                
                
                anchors[i].parentNode.replaceChild(schedule.getElm(), anchors[i]);
                
                break;
            }
        }
    }
    
    function cssClass(name) {
        return PREFIX+name;
    }
        
    function Schedule(baseUrl, PREFIX, professionalId, providerId, initialStartTime, initialProcedure) {
        var self = this;
        
        var _containerElm = document.createElement('div');
        _containerElm.className = PREFIX+'schedule';
        
	    var _scheduleContainerElm = document.createElement('div');
        _scheduleContainerElm.className = cssClass('location');
        _containerElm.appendChild(_scheduleContainerElm);
        
        var _specialtyPickerForm = createSpecialtyPicker();
		_scheduleContainerElm.appendChild(_specialtyPickerForm);
		
		var _reasonPickerForm = createReasonPicker();
		_scheduleContainerElm.appendChild(_reasonPickerForm);
		
		 var _scheduleTable = document.createElement('table');
        _scheduleContainerElm.appendChild(_scheduleTable);

			
        var _scheduleTableHeader = createSchedulePanelHeader();
        _scheduleTable.appendChild(_scheduleTableHeader);
        

        var _logo = document.createElement('div');
        _logo.className = cssClass('logo');
        //this will be reset after loading the model so that its provider/professional specific
        _logo.innerHTML = 'Powered by: <a href="http://www.zocdoc.com"><img src="http://www.zocdoc.com/images/remote_logo_sm.jpg" alt="ZocDoc" /></a>';
        _containerElm.appendChild(_logo);

        var _schedulePanels = new Array();
        var _model;
        
        updateModel(professionalId,providerId, initialStartTime, initialProcedure);
        
           
        this.getElm = function() {
            return _containerElm;
        };
        
        function createSpecialtyPicker() {
            var formElm = document.createElement('form');
            formElm.id = 'specialtyForm';
            formElm.innerHTML = 
                '<fieldset>' +
                    '<label>Specialty:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' +
                    '<select name="dr_specialty" ></select>' +
                '</label></fieldset>';
            
            var selectElm = formElm.getElementsByTagName('select')[0];
            selectElm.onchange = onSpecialtyChange;
            return formElm;
        }
        function createReasonPicker() {
            var formElm = document.createElement('form');
            formElm.id = 'reasonForm';
            formElm.innerHTML = 
                '<fieldset>' +
                    '<label>Visit Reason:' + 
                    '<select name="reason_visit" ></select>' +
                '</label></fieldset>';
            
            var selectElm = formElm.getElementsByTagName('select')[0];
            selectElm.onchange = onReasonChange;
            return formElm;
        }
        
         function createSchedulePanelHeader() {
            var thead = document.createElement('thead');
			var trElm = document.createElement('tr');
			thead.appendChild(trElm);
            
            var th_prevElm = document.createElement('th');
            th_prevElm.className = cssClass('prev_week');
            th_prevElm.innerHTML = '<a href="#">Prev.<br/>Week</a>';
            th_prevElm.getElementsByTagName('a')[0].onclick = onPrevClick;
            trElm.appendChild(th_prevElm);
            
            for(var i=0; i<7; i++) {
                var th = document.createElement('th');
                th.className = cssClass('calendar');
                th.innerHTML = 
                    '<span class="'+cssClass('day')+'"></span>' +
                    '<span class="'+cssClass('date')+'"></span>';
                
                trElm.appendChild(th);
            }
            
            var th_nextElm = document.createElement('th');
            th_nextElm.className = cssClass('next_week');
            th_nextElm.innerHTML = '<a href="#">Next<br/>Week</a>';
            th_nextElm.getElementsByTagName('a')[0].onclick = onNextClick;
            trElm.appendChild(th_nextElm);
            
            return thead;
        }
        
         function fillSchedulePanelHeader(timeSlotStart) {
	        var daysOfWeeks = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];

            var thElms = _scheduleTableHeader.getElementsByTagName('th');
          
            var day = new Date(timeSlotStart.getTime());

            for(var thElmIndex=1; thElmIndex<thElms.length - 1; thElmIndex++) {
                var thElm = thElms[thElmIndex];
                var dayElm = thElm.getElementsByTagName('span')[0];
                var dateElm = thElm.getElementsByTagName('span')[1];
                
                dayElm.innerHTML = daysOfWeeks[day.getDay()];
                dateElm.innerHTML = (day.getMonth()+1) + '/' + day.getDate() + '/' + day.getFullYear();
                
                day.setDate(day.getDate() + 1);
            }
        }
        function onPrevClick() {
		  //all professionals share the same prev page ticks and procedure so this is fine.
            if(_model)
                updateModel( null,1684,  _model[0].PrevPageTicks, _model[0].ProcedureId);
            return false;
        }
        function onNextClick() {
            if(_model)
                updateModel( null,1684, _model[0].NextPageTicks, _model[0].ProcedureId);
            return false;
        }
        
        function fillData(model) {
			 
			  _model = model;
			  
            //if there are no times available this week for any pro, get the first week when there are times
            var timesAvailable = true;
            var firstAppointmentTicks = 0;
            
            if(_firstLoad==true)
            {
                _firstLoad = false;
                timesAvailable = false;
                for(var counter =0; counter < _model.length; counter ++)
                {
                    if(_model[counter].Locations.length > 0 && _model[counter].Locations[0].TimeSlots.length > 0)
                    {
                        timesAvailable = true;
                        break;
                    } 
                    else if(_model[counter].Locations.length > 0 && _model[counter].Locations[0].TimeSlots.length ==0 &&  _model[counter].Locations[0].FirstAppointmentTicks)
                    {
                        if(firstAppointmentTicks ==0 || firstAppointmentTicks < _model[counter].Locations[0].FirstAppointmentTicks)
                        {
                            firstAppointmentTicks=_model[counter].Locations[0].FirstAppointmentTicks;
                        }
                    }
                }
            }
            
            //dont fast forward to the first avail week = patients dont notice.
//            if(false && timesAvailable ==false &&  firstAppointmentTicks >0)
//            {
//               updateModel(null,1684, firstAppointmentTicks, _model[0].procedureId); 
//            }
//            else
            {
			  
			  fillSchedulePanelHeader( new Date(model[0].TimeSlotsStart)); //all professionals share the same time slot start so this is fine.
			  
			  //set the drop downs
			  var specialtyId = null;
			  if(_specialtyPickerForm.getElementsByTagName('select')[0].childNodes.length == 0)
			  {
				  //the default specialty is the most common specialty at the practice
				  var specialties = [];
				  for(var i = 0; i < _model.length; i++) 
				  {
					  for(var k=0; k < _model[i].Procedures.length; k++)
					  {
						var specialtyFound = false;
						for(var j=0; j< specialties.length; j++)
						{
						  if(specialties[j][0] == _model[i].Procedures[k].SpecialtyId)
						  {
							specialtyFound = true;
							specialties[j][1] =  specialties[j][1] + 1;
							break;
						  }
						}
						if(!specialtyFound)
						{
						  specialties[specialties.length] = [_model[i].Procedures[k].SpecialtyId, 1, _model[i].Procedures[k].SpecialtyName];
						}
					  }
				  }
				 
    			  
    			  //now find the max
    			  var max = 0;
    			  for(var j=0; j< specialties.length; j++)
				  {
					if(specialties[j][1] > max)
					{
					  max = specialties[j][1];
					  specialtyId = specialties[j][0];
					}
				  } 
				  fillSpecialtyPicker(specialties, specialtyId);
			  }
			  else
			  {
				  if(_scheduleContainerElm.innerHTML != '')
				  {
					var selectElm = _specialtyPickerForm.getElementsByTagName('select')[0];
					var index = selectElm.selectedIndex;
					var option = selectElm.childNodes[index];
					specialtyId = option.value;
				  }
				  //else specialtyId is null
			  }
			  
			  //always refresh the reasons because we may have changed the specialty, this is inefficient, but its fast enough
			  populateResonPickerFromModel(specialtyId); 
			  
			  //clear the panels 
			  if(_scheduleTable.childNodes != null)
			  {
				for(var i = _scheduleTable.childNodes.length-1; i >= 1 ; i--)  //dont remove the header row though
				{
					_scheduleTable.removeChild(_scheduleTable.childNodes[i]);
	  				_schedulePanels.slice(i);
				}
			  }

              
              //add panels (it is simpler to clear and then re-add the panels than remove only certain ones)
              var panelCounter=0;
			  for(var i = 0; i < model.length; i++) 
			  {
				  //only show those who perform this procedure
				   var performsProcedure = false;
				   for(var j =0; j< model[i].Procedures.length; j++)
				   {
					  if(model[i].Procedures[j].Id == model[i].ProcedureId)
					  {
						performsProcedure = true;
						break;
					  }
				   }
				   
				   if(performsProcedure)
				   {
					var newSchedulePanel = new SchedulePanel(baseUrl, PREFIX, updateModel[i]);
					_schedulePanels[_schedulePanels.length] = newSchedulePanel;
					_scheduleTable.appendChild(newSchedulePanel.getElm());
					newSchedulePanel.fillData(model[i], panelCounter);
					panelCounter = panelCounter + 1;
				  }
			  }
			  
  			  //TODO -set this up to cover practice location
  			  var link = 'http://www.zocdoc.com';
			  if(model.length ==1)
			  {
			    link= model[0].ProfessionalUrl;
			  }
			  else
			  {
				link = model[0].ProviderUrl;
			  }
			  _logo.innerHTML = 'Powered by: <a href="' + link +  '"><img src="http://www.zocdoc.com/images/remote_logo_sm.jpg" alt="ZocDoc" /></a>';

            }
        };
        
        function populateResonPickerFromModel(specialtyId)
        {
						
			//get everyone's procedures
			  var proceduresList = [];
			  for(var i = 0; i < _model.length; i++) 
			  {
				 for(var j =0; j< _model[i].Procedures.length; j++)
				 {
					  var procedureFound = false;
					  for(var procedureCounter=0; procedureCounter< proceduresList.length; procedureCounter++)
					  {
						if(proceduresList[procedureCounter].Name == _model[i].Procedures[j].Name)
						{
						  procedureFound = true;
						  break;
						}
					  }
					  if(!procedureFound)
					  {
						//filter by specialty
						if(specialtyId == null ||_model[i].Procedures[j].SpecialtyId == specialtyId)
						{
						  proceduresList[proceduresList.length] = _model[i].Procedures[j];
						}
					  }
				 }
				
			  }
			  fillReasonPicker(proceduresList, _model[0].ProcedureId); //they all share the same procedure id, so this is fine.
        }
        function fillReasonPicker(procedures, selectedProcedureId) 
        {
            var selectElm = _reasonPickerForm.getElementsByTagName('select')[0];
            selectElm.innerHTML = '';
            
            for(var i=0; i<procedures.length; i++) {
                var optionElm = document.createElement('option');
                optionElm.value = procedures[i].Id;
                
                if(procedures[i].Id == selectedProcedureId)
                    optionElm.selected = true;
                
                optionElm.innerHTML = procedures[i].Name;
                selectElm.appendChild(optionElm);
            }
        }
        
        //note that specialties is a 2d array, unlike procedures which is a list of procedure objects
        function fillSpecialtyPicker(specialties, selectedSepecialtyId) 
        {
			if(specialties.length > 1)
			{
				_specialtyPickerForm.style.cssText = ''; //clear the display:none tag
				var selectElm = _specialtyPickerForm.getElementsByTagName('select')[0];
				selectElm.innerHTML = '';
                
				for(var i=0; i<specialties.length; i++) {
					var optionElm = document.createElement('option');
					optionElm.value = specialties[i][0];
                    
					if(specialties[i][0] == selectedSepecialtyId)
						optionElm.selected = true;
                    
					optionElm.innerHTML = specialties[i][2];
					selectElm.appendChild(optionElm);
				}
			}
            else
            {
				//remove
				var specialtyForm =  document.getElementById('specialtyForm');
				if(specialtyForm !=null)
				{
				  //IE freaks if you use _scheduleContainerElm.removeChild(specialtyForm);
				 specialtyForm.parentNode.removeChild(specialtyForm);
				}
            }
        }
        
        function updateModel(professionalId, providerId, startTicks, procedureId) {
            var nowTicks = (new Date()).getTime();
            
            while(nowTicks ==(new Date()).getTime());
        
            var callbackName = 'jsonp' + nowTicks;

            var script = document.createElement('script');
            script.setAttribute("type", "text/javascript");
            script.setAttribute("id", ""+callbackName);
            
            var url = baseUrl + '/remote/ScheduleData.js.ashx?from=' + escape(document.location) + '&';
            if(professionalId !=null)
            {
			  url = url + 'id='+professionalId;
            }
            else  if(providerId !=null)
            {
			  url = url + 'providerId='+providerId;
            }
            
            if(startTicks)
                url += ('&starttime=' + startTicks);
            if(procedureId)
                url += ('&reason_visit='+ procedureId);
            
            url += '&callback=' + callbackName;
            url += ('&random='+(new Date()).getTime());
            
            script.setAttribute("src", url);
            
            document.getElementsByTagName('head')[0].appendChild(script);

            window[callbackName] = function(m) {
                document.getElementById(callbackName).parentNode.removeChild(document.getElementById(callbackName));
                fillData(m);
                window[callbackName] = null;
            };
        };
        
        function onSpecialtyChange() 
        {
            var selectElm = this;
            var index = selectElm.selectedIndex;
            var option = selectElm.childNodes[index];
            var specialtyId = option.value;
            
            //get the most popular procedure that professionals in this model perform under this specialty
            var procedureId=null;
            var procedures = [];
			for(var i = 0; i < _model.length; i++) 
			{
				for(var k=0; k < _model[i].Procedures.length; k++)
				{
				  if(_model[i].Procedures[k].SpecialtyId == specialtyId)
				  {
					  var procedureFound = false;
					  for(var j=0; j< procedures.length; j++)
					  {
						if(procedures[j][0] == _model[i].Procedures[k].Id)
						{
						  procedureFound = true;
						  procedures[j][1] =  procedures[j][1] + 1;
						  break;
						}
					  }
					  if(!procedureFound)
					  {
						procedures[procedures.length] = [_model[i].Procedures[k].Id, 1];
					  }
				  }
				}
			}
  		 
  			  
			//now find the max
			var max = 0;
			for(var j=0; j< procedures.length; j++)
			{
			  if(procedures[j][1] > max)
			  {
				max = procedures[j][1];
				procedureId = procedures[j][0];
			  }
			} 
            
            updateModel(null,1684, _model[0].CurrentPageTicks, procedureId);
        
        }
        function onReasonChange() {
            var selectElm = this;
            var index = selectElm.selectedIndex;
            var option = selectElm.childNodes[index];
            var procedureId = option.value;
            
            updateModel(null,1684, _model[0].CurrentPageTicks, procedureId);
        }
    }
    Schedule.jsonpCount = 0;

    function SchedulePanel(baseUrl, PREFIX, updateModelFn) {
        
        var _scheduleTableBody = createSchedulePanelBody();
      
        var _model = null;

        this.getElm = function() {
            return _scheduleTableBody;
        };
        
        this.dispose = function() {
            var anchors = _scheduleTableBody.getElementsByTagName('a');
            
            for(var i=0; i<anchors.length; i++)
                anchors[i].onclick = null;
        };


        function createSchedulePanelBody() {
            var tbodyElm = document.createElement('tbody');
            var trElm = document.createElement('tr');
            tbodyElm.appendChild(trElm);
            
            var td_prevElm = document.createElement('td');
            td_prevElm.className = cssClass('prev_week');
            td_prevElm.innerHTML = '&nbsp;';
            trElm.appendChild(td_prevElm);
            
            for(var i=0; i<7; i++) { 
                var tdElm = document.createElement('td');
                var tdClass = cssClass('calendar');
                if(i%2 == 1) tdClass += " " + cssClass('alt');
                tdElm.className = tdClass;
                
                trElm.appendChild(tdElm);
            }
            
            var td_nextElm = document.createElement('td');
            td_nextElm.className = cssClass('next_week');
            td_nextElm.innerHTML = '&nbsp;';
            trElm.appendChild(td_nextElm);

            return tbodyElm;
        }

        this.fillData = function(model, index) {
            _model = model;
            
            fillScheduleBody(model, model.Locations[0]); //TODO- we are assuming that there is only 1 location...
        };
        
        function fillScheduleBody(model, location) {
			var maxPerDay = 5;
            var tdElms = _scheduleTableBody.getElementsByTagName('td');
            
            //if there are only 3 table cells (previously they didnt have any appointments) create the date cells again
            if(tdElms.length == 3)
            {
			  var parent = tdElms[0].parentNode;
			  parent.removeChild(parent.childNodes[1]);
			   
			   for(var i=0; i<7; i++) 
			   { 
				  var tdElm = document.createElement('td');
				  var tdClass = cssClass('calendar');
				  if(i%2 == 1) tdClass += " " + cssClass('alt');
				  tdElm.className = tdClass;
                  
				  parent.insertBefore(tdElm,parent.lastChild);
			   }
            
			  tdElms = parent.getElementsByTagName('td');
            }
            
            //clear prev values
            for(var i=0; i<tdElms.length - 1; i++) {
                 tdElms[i].innerHTML = '';
            }
            
            //add photo and name
             
                var nameElem2 =document.createElement('a');
                nameElem2.href = model.ProfessionalUrl;
                nameElem2.setAttribute('style','text-decoration:none;');

             
				 var photoElm = document.createElement('img');
				 photoElm.src = "http://offsiteSchedule.zocdoc.com" + model.ProfessionalImageUrl;
				 photoElm.setAttribute("alt", model.ProfessionalFullName);
				 photoElm.setAttribute("title", model.ProfessionalFullName);
				 photoElm.className = "photo";
				 nameElem2.appendChild(photoElm);
				 
				 tdElms[0].appendChild(nameElem2); 
			
             
              var nameElem =document.createElement('a');
             nameElem.href = model.ProfessionalUrl;
             nameElem.innerHTML = "<nobr>" + model.ProfessionalFullName + "</nobr>";
             tdElms[0].appendChild(nameElem); 

            
            
            var oneDayInMs=1000*60*60*24;
            if(location.TimeSlots.length > 0 )
            {
                //we need to strip the time from the TimeSlotsStart
                var startDate = new Date(model.TimeSlotsStart);
                startDate.setHours(0);
                startDate.setMinutes(0);
                startDate.setSeconds(0);
                
			  for(var timeSlotIndex=0; timeSlotIndex < location.TimeSlots.length; timeSlotIndex++) 
			  {
				  var timeSlot = location.TimeSlots[timeSlotIndex];
				  var startTime = new Date(timeSlot.StartTime);
				  var dayIndex = Math.floor((startTime - startDate)/oneDayInMs);
                  
				  if(dayIndex >= 7) 
					  continue;
                  
				  var aElm = document.createElement('a');
				  aElm.setAttribute("rel","nofollow");
				  aElm.href = 
					  url("http://www.zocdoc.com/sanction.aspx", { //we use www instead of the base url which is offsiteSchedule.zocdoc.com which isnt for users
						  professional: model.ProfessionalId, 
						  location: location.Id, 
						  timeslotid: timeSlot.Id, 
						  startTime: timeSlot.StartTimeTicks,
						  reason_visit: model.ProcedureId,
						  insurance_carrier: -1,
						  insurance_plan: -1,
						  dr_specialty: model.SpecialtyId,
						  lock:true,
						  referrerType: 'Widget' });
                  
				  var tempMins = startTime.getMinutes();
				  tempMins = (tempMins < 10)? ("0" + tempMins) : tempMins;
                  
				  aElm.innerHTML = "<nobr>" + 
					  ((startTime.getHours()%12) || 12) + 
					  ":" + 
					  (tempMins || "00") + 
					  " " + 
					  ((startTime.getHours() >= 12)? "PM" : "AM") +  "</nobr>";
                      
				  if (tdElms[dayIndex+1].childNodes.length < maxPerDay)
				  {
					tdElms[dayIndex+1].appendChild(aElm);
				  }
				  else if(tdElms[dayIndex+1].childNodes.length == maxPerDay)
				  {  
					 
					 var procedureParam = '';
					 procedureParam = "?reason_visit=" + model.ProcedureId;
					 
					 var startTimeParam = '';
					 if(startTime != Date.Today)
					 {
					  //the profile page takes the start date and then -3 to get the begining of the week, which is why this is a separate variable
					  startTimeParam = "&starttime=" + model.ProfilePageCurrentPageTicks; 
					 }
					 
					 var moreLink = document.createElement('center');
					 moreLink.innerHTML = "<a rel=\"nofollow\" href=\"" + model.ProfessionalUrl + procedureParam + startTimeParam + "&lock=true\">more...</a>";
					 tdElms[dayIndex+1].appendChild(moreLink);
				  }
				  //note that after we add the 'more' link, the child nodes = maxPerDay +1
				 }
			  }
			  else //no times
			  {
				//extend the second column over 6 columns
				tdElms[1].setAttribute("colSpan","7");
				tdElms[1].innerHTML = "<div class='noAvail'><br/><nobr>This " + model.MainSpecialtyName + " has no availability this week.</nobr></div>";
  			  
				//remove the others
				var row = tdElms[0].parentNode;
				for(var i=tdElms.length - 2; i>1; i--) //-2 so that we dont remove the 'next week' column.
				{ 
				   row.removeChild(tdElms[i]);
				}
		  }
        }
        function url(page, params) {
            var buff = page;
            
            var isFirst = true;
            for(var param in params) {
                buff += isFirst? "?" : "&";
                buff += param + "=" + params[param];
                
                isFirst = false;
            }
            
            return buff;
        }
        
        
    }
})();

 


