# install required packages
install.packages("readxl")

# importing required packages
library(readxl)	

# define where to read "climate.xlsx".
path <- "climate.xlsx"

# Since there are multi-sheets in the xlsx,
# we have to read all of it and integrate them.

# read the sheets name.
sheets_name <- excel_sheets(path)

# create the empty data frame to store all of data.
cilmateData <- NULL

# Because there are no city name in the original data, 
# it is necessary to add before the integration
city_name <- c('Swansea', 'Wuhan')

# for every sheets in the xlsx,
for (i in seq(sheets_name))
{
  # read the content as data frame
  tempData <- read_excel(path, sheet = sheets_name[i])
  
  # repeat city name to generate vector
  City <- rep(city_name[i], nrow(tempData))
  
  # use cbind to combine city name and city content
  tempData <- cbind(City, tempData)
  
  # use rbind to store each sheet's content
  cilmateData <- rbind(cilmateData, tempData)
}

# fill in the missing column names.
colnames(cilmateData)[2] <- 'Weather'

# city is imported as a factor
cilmateData$City <- factor(cilmateData$City)

# for clear environment, remove the temp data.
rm(tempData, City, i, path, sheets_name)

# define each month's day
each_month_day <- c(31, 28, 31, 30, 31, 30,
                    31, 31, 30, 31, 30, 31)

# create empty vector to store cumulative value.
cumulative <- NULL

# for each city,
for (i in seq(city_name))
{
  # filter this city's data.
  cityData <- cilmateData[cilmateData$City == city_name[i],]
  
  # filter the Rainy days of this city.
  cityRainData <- cityData[cityData$Weather == 'Rainy days (d)',]
  
  # sum all of the month's data.
  sumRainDay <- sum(cityRainData[,3:length(cityRainData)])
  
  # store it to vector.
  cumulative <- c(cumulative, sumRainDay)
  
  # filter the Avg. Sun hours of this city.
  cityAvgSunHour <- cityData[cityData$Weather == 'Avg. Sun hours (hours)',]
  
  # create the variable to sum every month's sun hours
  sumSunHour <- 0
  
  # for every month,
  for (j in seq(each_month_day))
  {
    # month's cumulative Sun hours = month's Avg. Sun hours * month's day
    sumMonthSunHour <- each_month_day[j] * as.numeric(cityAvgSunHour[j+2])
    
    # add it to sumSunHour.
    sumSunHour <- sumSunHour + sumMonthSunHour
  }
  
  # store sumSunHour to vector.
  cumulative <- c(cumulative, sumSunHour)
}

# Use the city name, cumulative project and value to create data frame.
cumulativeData <- data.frame(
  City = rep(city_name, each = 2),
  Cumulative = rep(c('Rainy days', 'Sun Hours'), 2),
  Value = cumulative
  )


# define function displayGraph that will take the city name weather parameter 
# and will produce a line graph of that weather parameter over the year for that city.
displayGraph <- function(city, weather)
{
  # filter city data.
  cityData <- cilmateData[cilmateData$City == city,]
  
  # filter weather of city data.
  cityWeatherData <- cityData[cityData$Weather == weather,]
  
  # get every month's city weather data and change them into numeric.
  cityWeather <- as.numeric(cityWeatherData[,3:length(cityWeatherData)])
  
  # get the column names of every month as the x axis name.
  Month <- colnames(cityWeatherData)[3:length(cityWeatherData)]
  
  # define the heading of graph.
  heading <- paste("The line graph of", weather, "over the year for", city)
  
  # produce a line graph of that weather parameter over the year for that city.
  plot(1:12, cityWeather, type='l', xaxt='n', col='green', lwd=4, 
       xlab='Month', ylab=weather, main=heading)
  
  # display the x axis name
  axis(1, at = 1:12, labels = Month)
}

# Use the function to display Wuhan 's humidity.
displayGraph('Wuhan', 'Humidity(%)')

# Use the function to display Swansea's rainy days.
displayGraph('Swansea', 'Rainy days (d)')


# define function compareCities that will take two weather parameters, 
# and will plot the data for those parameters for both cities on the same graph.
compareCities <- function(weather1, weather2)
{
  # Mean temperature and humidity, if displayed, should be shown as line graphs,
  # while all other weather parameters should be shown as bar plots.
  show_line_graph <- c('Avg. Temperature ˇăC', 'Humidity(%)')
  
  # define the color.
  city_color1 <- c('green', 'darkgreen')
  city_color2 <- c('blue', 'cornflowerblue')
  
  # filter each weather's data
  weatherData1 <- cilmateData[cilmateData$Weather == weather1,]
  weatherData2 <- cilmateData[cilmateData$Weather == weather2,]
  
  # divide weather data into different city
  SwanseaWeather1 <- as.numeric(weatherData1[1, 3:length(weatherData1)])
  SwanseaWeather2 <- as.numeric(weatherData2[1, 3:length(weatherData2)])
  
  WuhanWeather1 <- as.numeric(weatherData1[2, 3:length(weatherData1)])
  WuhanWeather2 <- as.numeric(weatherData2[2, 3:length(weatherData2)])
  
  # For the plot display to be reasonable, 
  # the minimum and maximum value needs to be known.
  minValue1 <- min(c(SwanseaWeather1, WuhanWeather1))
  minValue2 <- min(c(SwanseaWeather2, WuhanWeather2))
  
  maxValue1 <- max(c(SwanseaWeather1, WuhanWeather1))
  maxValue2 <- max(c(SwanseaWeather2, WuhanWeather2))
  
  # get the column names of every month as the x axis name.
  Month <- colnames(weatherData1)[3:length(weatherData1)]
  
  # since there are two y axis, 
  # the size of the canvas needs to be modified a bit.
  par(mar = c(5, 4, 4, 4) + 0.3)
  
  # judge which type of plot to display
  if (weather1 %in% show_line_graph){
    # plot the first weather of Swansea
    plot(1:12, SwanseaWeather1, type='l', xaxt='n', col=city_color1[1], lwd=4, 
         xlab='Month', ylab=weather1, ylim=range(minValue1, maxValue1))
    
    # plot the first weather of Wuhan
    lines(1:12, WuhanWeather1, col=city_color1[2], lwd=4)
    
    # display the x axis name
    axis(1, at = 1:12, labels = Month)
  } else
  {
    # use rbind to combined first weather of Swansea and Wuhan
    bindWeather <- rbind(SwanseaWeather1, WuhanWeather1)
    
    # plot the beside bar.
    barplot(bindWeather, names.arg = Month, col=city_color1,
            xlab='Month', ylab=weather1, beside=T)
  }
  
  # in the same graph, plot the second weather.
  par(new=TRUE)
  
  # the procedure to plot the second weather is similar with the first one,
  # however, when plot, there should not display x and y axis value and name,
  # and fill them by hand when needed.
  if (weather2 %in% show_line_graph){
    plot(1:12, SwanseaWeather2, type = 'l', col = city_color2[1], lwd = 4,
         axes = FALSE, bty = "n", xlab = "", ylab = "", 
         ylim = range(minValue2, maxValue2))
    axis(side = 4, at = pretty(range(minValue2, maxValue2)))
    mtext(weather2, side = 4, line = 3)
    lines(1:12, WuhanWeather2, col = city_color2[2], lwd = 4)
  } else
  {
    bindWeather <- rbind(SwanseaWeather2, WuhanWeather2)
    barplot(bindWeather, col = city_color2, density = 20, beside = T, axes = F)
    axis(side = 4, at = pretty(range(minValue2, maxValue2)))
    mtext(weather2, side = 4, line = 3)
  }
  
  # create heading of the plot.
  title(paste("Compare both", weather1, "and", weather2, "of Swansea and Wuhan"))
  
  # create the legend of the plot.
  legend(1, maxValue2, city_name, lwd = c(4,4), col = city_color1, y.intersp=0.3)
}

# Use the function to compare Avg. Temperature and Avg. Sun hours.
compareCities('Avg. Temperature ˇăC', 'Avg. Sun hours (hours)')